]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/rs6000/rs6000.md
Daily bump.
[thirdparty/gcc.git] / gcc / config / rs6000 / rs6000.md
CommitLineData
996a5f59 1;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
a260abc9 2;; Copyright (C) 1990, 91-97, 1998 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.
b7ff3d82 26(define_attr "type" "integer,load,store,fpload,fpstore,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
b7ff3d82 43(define_attr "cpu" "rios1,rios2,mpccore,ppc403,ppc601,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
b7ff3d82 49; Load/Store Unit -- pure PowerPC only
51b8fc2c 50; (POWER and 601 use Integer Unit)
cfb557c4
RK
51(define_function_unit "lsu" 1 0
52 (and (eq_attr "type" "load")
b7ff3d82 53 (eq_attr "cpu" "mpccore,ppc603,ppc604,ppc620"))
b6c9286a 54 2 1)
cfb557c4
RK
55
56(define_function_unit "lsu" 1 0
b7ff3d82
DE
57 (and (eq_attr "type" "store,fpstore")
58 (eq_attr "cpu" "mpccore,ppc603,ppc604,ppc620"))
59 1 1)
b6c9286a
MM
60
61(define_function_unit "lsu" 1 0
62 (and (eq_attr "type" "fpload")
b7ff3d82 63 (eq_attr "cpu" "mpccore,ppc603"))
b6c9286a 64 2 1)
cfb557c4 65
b7ff3d82
DE
66(define_function_unit "lsu" 1 0
67 (and (eq_attr "type" "fpload")
68 (eq_attr "cpu" "ppc604,ppc620"))
69 3 1)
70
cfb557c4
RK
71(define_function_unit "iu" 1 0
72 (and (eq_attr "type" "load")
b7ff3d82 73 (eq_attr "cpu" "rios1,ppc403,ppc601"))
b6c9286a 74 2 1)
cfb557c4
RK
75
76(define_function_unit "iu" 1 0
b7ff3d82
DE
77 (and (eq_attr "type" "store,fpstore")
78 (eq_attr "cpu" "rios1,ppc403,ppc601"))
79 1 1)
80
81(define_function_unit "fpu" 1 0
82 (and (eq_attr "type" "fpstore")
3624a679 83 (eq_attr "cpu" "rios1,ppc601"))
b7ff3d82 84 0 1)
cfb557c4 85
49a0b204 86(define_function_unit "iu" 1 0
b7ff3d82 87 (and (eq_attr "type" "fpload")
b6c9286a 88 (eq_attr "cpu" "rios1"))
b7ff3d82
DE
89 2 1)
90
91(define_function_unit "iu" 1 0
92 (and (eq_attr "type" "fpload")
93 (eq_attr "cpu" "ppc601"))
94 3 1)
95
96(define_function_unit "iu2" 2 0
97 (and (eq_attr "type" "load,fpload")
98 (eq_attr "cpu" "rios2"))
99 2 1)
100
101(define_function_unit "iu2" 2 0
102 (and (eq_attr "type" "store,fpstore")
103 (eq_attr "cpu" "rios2"))
104 1 1)
105
106; Integer Unit (RIOS1, PPC601, PPC603)
107(define_function_unit "iu" 1 0
108 (and (eq_attr "type" "integer")
109 (eq_attr "cpu" "rios1,mpccore,ppc403,ppc601,ppc603"))
110 1 1)
49a0b204 111
da0ae67f
MM
112(define_function_unit "iu" 1 0
113 (and (eq_attr "type" "imul")
114 (eq_attr "cpu" "ppc403"))
115 4 4)
116
cfb557c4
RK
117(define_function_unit "iu" 1 0
118 (and (eq_attr "type" "imul")
b7ff3d82 119 (eq_attr "cpu" "rios1,ppc601,ppc603"))
51b8fc2c 120 5 5)
cfb557c4
RK
121
122(define_function_unit "iu" 1 0
123 (and (eq_attr "type" "idiv")
ca7f5001 124 (eq_attr "cpu" "rios1"))
51b8fc2c 125 19 19)
cfb557c4
RK
126
127(define_function_unit "iu" 1 0
128 (and (eq_attr "type" "idiv")
b7ff3d82
DE
129 (eq_attr "cpu" "ppc403"))
130 33 33)
51b8fc2c 131
da0ae67f
MM
132(define_function_unit "iu" 1 0
133 (and (eq_attr "type" "idiv")
b7ff3d82
DE
134 (eq_attr "cpu" "ppc601"))
135 36 36)
da0ae67f 136
51b8fc2c
RK
137(define_function_unit "iu" 1 0
138 (and (eq_attr "type" "idiv")
b7ff3d82 139 (eq_attr "cpu" "ppc603"))
51b8fc2c
RK
140 37 36)
141
142; RIOS2 has two integer units: a primary one which can perform all
143; operations and a secondary one which is fed in lock step with the first
b6c9286a
MM
144; and can perform "simple" integer operations.
145; To catch this we define a 'dummy' imuldiv-unit that is also needed
146; for the complex insns.
51b8fc2c
RK
147(define_function_unit "iu2" 2 0
148 (and (eq_attr "type" "integer")
149 (eq_attr "cpu" "rios2"))
b7ff3d82 150 1 1)
b6c9286a
MM
151
152(define_function_unit "iu2" 2 0
153 (and (eq_attr "type" "imul")
154 (eq_attr "cpu" "rios2"))
155 2 2)
156
157(define_function_unit "iu2" 2 0
158 (and (eq_attr "type" "idiv")
159 (eq_attr "cpu" "rios2"))
160 13 13)
51b8fc2c
RK
161
162(define_function_unit "imuldiv" 1 0
163 (and (eq_attr "type" "imul")
164 (eq_attr "cpu" "rios2"))
b6c9286a
MM
165 2 2)
166
51b8fc2c
RK
167(define_function_unit "imuldiv" 1 0
168 (and (eq_attr "type" "idiv")
169 (eq_attr "cpu" "rios2"))
b6c9286a 170 13 13)
51b8fc2c 171
cf27b467
MM
172; MPCCORE has separate IMUL/IDIV unit for multicycle instructions
173; Divide latency varies greatly from 2-11, use 6 as average
174(define_function_unit "imuldiv" 1 0
175 (and (eq_attr "type" "imul")
176 (eq_attr "cpu" "mpccore"))
177 2 1)
178
179(define_function_unit "imuldiv" 1 0
180 (and (eq_attr "type" "idiv")
181 (eq_attr "cpu" "mpccore"))
182 6 6)
183
b6c9286a
MM
184; PPC604 has two units that perform integer operations
185; and one unit for divide/multiply operations (and move
186; from/to spr).
187(define_function_unit "iu2" 2 0
51b8fc2c
RK
188 (and (eq_attr "type" "integer")
189 (eq_attr "cpu" "ppc604,ppc620"))
b7ff3d82 190 1 1)
51b8fc2c
RK
191
192(define_function_unit "imuldiv" 1 0
193 (and (eq_attr "type" "imul")
194 (eq_attr "cpu" "ppc604,ppc620"))
b7ff3d82 195 4 2)
51b8fc2c
RK
196
197(define_function_unit "imuldiv" 1 0
198 (and (eq_attr "type" "idiv")
199 (eq_attr "cpu" "ppc604,ppc620"))
b7ff3d82 200 20 19)
cfb557c4 201
b6c9286a 202; compare is done on integer unit, but feeds insns which
acc5239d 203; execute on the branch unit.
b6c9286a
MM
204(define_function_unit "iu" 1 0
205 (and (eq_attr "type" "compare")
b7ff3d82
DE
206 (eq_attr "cpu" "rios1"))
207 4 1)
208
209(define_function_unit "iu" 1 0
210 (and (eq_attr "type" "delayed_compare")
211 (eq_attr "cpu" "rios1"))
212 5 1)
213
214(define_function_unit "iu" 1 0
215 (and (eq_attr "type" "compare,delayed_compare")
216 (eq_attr "cpu" "mpccore,ppc403,ppc601,ppc603,ppc604,ppc620"))
217 3 1)
b6c9286a
MM
218
219(define_function_unit "iu2" 2 0
b7ff3d82 220 (and (eq_attr "type" "compare,delayed_compare")
b6c9286a 221 (eq_attr "cpu" "rios2"))
b7ff3d82 222 3 1)
b6c9286a 223
b6c9286a 224(define_function_unit "iu2" 2 0
b7ff3d82 225 (and (eq_attr "type" "compare,delayed_compare")
b6c9286a
MM
226 (eq_attr "cpu" "ppc604,ppc620"))
227 1 1)
cfb557c4 228
b6c9286a
MM
229; fp compare uses fp unit
230(define_function_unit "fpu" 1 0
cfb557c4 231 (and (eq_attr "type" "fpcompare")
b6c9286a 232 (eq_attr "cpu" "rios1"))
b7ff3d82 233 9 1)
cfb557c4 234
b6c9286a
MM
235; rios1 and rios2 have different fpcompare delays
236(define_function_unit "fpu2" 2 0
cfb557c4 237 (and (eq_attr "type" "fpcompare")
b6c9286a
MM
238 (eq_attr "cpu" "rios2"))
239 5 1)
240
241; on ppc601 and ppc603, fpcompare takes also 2 cycles from
242; the integer unit
243; here we do not define delays, just occupy the unit. The dependencies
b7ff3d82 244; will be assigned by the fpcompare definition in the fpu.
b6c9286a
MM
245(define_function_unit "iu" 1 0
246 (and (eq_attr "type" "fpcompare")
b7ff3d82 247 (eq_attr "cpu" "ppc601,ppc603"))
b6c9286a
MM
248 0 2)
249
250; fp compare uses fp unit
251(define_function_unit "fpu" 1 0
252 (and (eq_attr "type" "fpcompare")
b7ff3d82 253 (eq_attr "cpu" "ppc601,ppc603,ppc604,ppc620"))
b6c9286a 254 5 1)
cfb557c4 255
cf27b467
MM
256(define_function_unit "fpu" 1 0
257 (and (eq_attr "type" "fpcompare")
258 (eq_attr "cpu" "mpccore"))
259 1 1)
260
cfb557c4 261(define_function_unit "bpu" 1 0
324e52cc 262 (and (eq_attr "type" "mtjmpr")
2661cdd9 263 (eq_attr "cpu" "rios1,rios2"))
b7ff3d82 264 5 1)
cfb557c4
RK
265
266(define_function_unit "bpu" 1 0
324e52cc 267 (and (eq_attr "type" "mtjmpr")
b7ff3d82
DE
268 (eq_attr "cpu" "mpccore,ppc403,ppc601,ppc603,ppc604,ppc620"))
269 4 1)
cfb557c4 270
b6c9286a
MM
271; all jumps/branches are executing on the bpu, in 1 cycle, for all machines.
272(define_function_unit "bpu" 1 0
273 (eq_attr "type" "jmpreg")
b7ff3d82 274 1 1)
b6c9286a
MM
275
276(define_function_unit "bpu" 1 0
277 (eq_attr "type" "branch")
b7ff3d82 278 1 1)
b6c9286a 279
cf27b467 280; Floating Point Unit
cfb557c4 281(define_function_unit "fpu" 1 0
51b8fc2c 282 (and (eq_attr "type" "fp,dmul")
2661cdd9 283 (eq_attr "cpu" "rios1"))
b7ff3d82 284 2 1)
cfb557c4 285
cf27b467
MM
286(define_function_unit "fpu" 1 0
287 (and (eq_attr "type" "fp")
288 (eq_attr "cpu" "mpccore"))
289 4 4)
290
cfb557c4
RK
291(define_function_unit "fpu" 1 0
292 (and (eq_attr "type" "fp")
51b8fc2c 293 (eq_attr "cpu" "ppc601"))
b7ff3d82 294 4 1)
cfb557c4 295
51b8fc2c
RK
296(define_function_unit "fpu" 1 0
297 (and (eq_attr "type" "fp")
b7ff3d82 298 (eq_attr "cpu" "ppc603,ppc604,ppc620"))
b6c9286a 299 3 1)
51b8fc2c 300
cf27b467
MM
301(define_function_unit "fpu" 1 0
302 (and (eq_attr "type" "dmul")
303 (eq_attr "cpu" "mpccore"))
304 5 5)
305
cfb557c4
RK
306(define_function_unit "fpu" 1 0
307 (and (eq_attr "type" "dmul")
51b8fc2c 308 (eq_attr "cpu" "ppc601"))
b6c9286a 309 5 2)
cfb557c4 310
b6c9286a 311; is this true?
cfb557c4
RK
312(define_function_unit "fpu" 1 0
313 (and (eq_attr "type" "dmul")
b7ff3d82 314 (eq_attr "cpu" "ppc603"))
51b8fc2c 315 4 2)
cfb557c4
RK
316
317(define_function_unit "fpu" 1 0
51b8fc2c
RK
318 (and (eq_attr "type" "dmul")
319 (eq_attr "cpu" "ppc604,ppc620"))
b6c9286a 320 3 1)
51b8fc2c
RK
321
322(define_function_unit "fpu" 1 0
323 (and (eq_attr "type" "sdiv,ddiv")
2661cdd9 324 (eq_attr "cpu" "rios1"))
51b8fc2c 325 19 19)
cfb557c4
RK
326
327(define_function_unit "fpu" 1 0
328 (and (eq_attr "type" "sdiv")
51b8fc2c
RK
329 (eq_attr "cpu" "ppc601"))
330 17 17)
331
cf27b467
MM
332(define_function_unit "fpu" 1 0
333 (and (eq_attr "type" "sdiv")
334 (eq_attr "cpu" "mpccore"))
335 10 10)
336
51b8fc2c
RK
337(define_function_unit "fpu" 1 0
338 (and (eq_attr "type" "sdiv")
b7ff3d82 339 (eq_attr "cpu" "ppc603,ppc604,ppc620"))
51b8fc2c 340 18 18)
cfb557c4 341
cf27b467
MM
342(define_function_unit "fpu" 1 0
343 (and (eq_attr "type" "ddiv")
344 (eq_attr "cpu" "mpccore"))
345 17 17)
346
cfb557c4
RK
347(define_function_unit "fpu" 1 0
348 (and (eq_attr "type" "ddiv")
51b8fc2c
RK
349 (eq_attr "cpu" "ppc601,ppc604,ppc620"))
350 31 31)
cfb557c4
RK
351
352(define_function_unit "fpu" 1 0
353 (and (eq_attr "type" "ddiv")
b7ff3d82 354 (eq_attr "cpu" "ppc603"))
51b8fc2c 355 33 33)
cfb557c4
RK
356
357(define_function_unit "fpu" 1 0
358 (and (eq_attr "type" "ssqrt")
a473029f 359 (eq_attr "cpu" "ppc620"))
51b8fc2c 360 31 31)
cfb557c4
RK
361
362(define_function_unit "fpu" 1 0
363 (and (eq_attr "type" "dsqrt")
a473029f 364 (eq_attr "cpu" "ppc620"))
51b8fc2c 365 31 31)
b73d04f2 366
51b8fc2c 367; RIOS2 has two symmetric FPUs.
cfb557c4
RK
368(define_function_unit "fpu2" 2 0
369 (and (eq_attr "type" "fp")
4652f1d4 370 (eq_attr "cpu" "rios2"))
b7ff3d82 371 2 1)
cfb557c4
RK
372
373(define_function_unit "fpu2" 2 0
374 (and (eq_attr "type" "dmul")
375 (eq_attr "cpu" "rios2"))
b7ff3d82 376 2 1)
cfb557c4
RK
377
378(define_function_unit "fpu2" 2 0
51b8fc2c 379 (and (eq_attr "type" "sdiv,ddiv")
cfb557c4 380 (eq_attr "cpu" "rios2"))
51b8fc2c 381 17 17)
ca7f5001
RK
382
383(define_function_unit "fpu2" 2 0
51b8fc2c 384 (and (eq_attr "type" "ssqrt,dsqrt")
ca7f5001 385 (eq_attr "cpu" "rios2"))
51b8fc2c 386 26 26)
b6c9286a 387
1fd4e8c1
RK
388\f
389;; Start with fixed-point load and store insns. Here we put only the more
390;; complex forms. Basic data transfer is done later.
391
51b8fc2c
RK
392(define_expand "zero_extendqidi2"
393 [(set (match_operand:DI 0 "gpc_reg_operand" "")
394 (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "")))]
395 "TARGET_POWERPC64"
396 "")
397
398(define_insn ""
399 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
400 (zero_extend:DI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
401 "TARGET_POWERPC64"
402 "@
403 lbz%U1%X1 %0,%1
4371f8af 404 rldicl %0,%1,0,56"
51b8fc2c
RK
405 [(set_attr "type" "load,*")])
406
407(define_insn ""
408 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
409 (compare:CC (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r"))
410 (const_int 0)))
411 (clobber (match_scratch:DI 2 "=r"))]
58e09803 412 "TARGET_POWERPC64"
4371f8af 413 "rldicl. %2,%1,0,56"
51b8fc2c
RK
414 [(set_attr "type" "compare")])
415
416(define_insn ""
417 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
418 (compare:CC (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r"))
419 (const_int 0)))
420 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
421 (zero_extend:DI (match_dup 1)))]
58e09803 422 "TARGET_POWERPC64"
4371f8af 423 "rldicl. %0,%1,0,56"
51b8fc2c
RK
424 [(set_attr "type" "compare")])
425
2bee0449
RK
426(define_insn "extendqidi2"
427 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
428 (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r")))]
51b8fc2c 429 "TARGET_POWERPC64"
2bee0449 430 "extsb %0,%1")
51b8fc2c
RK
431
432(define_insn ""
433 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
434 (compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r"))
435 (const_int 0)))
436 (clobber (match_scratch:DI 2 "=r"))]
437 "TARGET_POWERPC64"
438 "extsb. %2,%1"
439 [(set_attr "type" "compare")])
440
441(define_insn ""
442 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
443 (compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r"))
444 (const_int 0)))
445 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
446 (sign_extend:DI (match_dup 1)))]
447 "TARGET_POWERPC64"
448 "extsb. %0,%1"
449 [(set_attr "type" "compare")])
450
451(define_expand "zero_extendhidi2"
452 [(set (match_operand:DI 0 "gpc_reg_operand" "")
453 (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" "")))]
454 "TARGET_POWERPC64"
455 "")
456
457(define_insn ""
458 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
459 (zero_extend:DI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
460 "TARGET_POWERPC64"
461 "@
462 lhz%U1%X1 %0,%1
4371f8af 463 rldicl %0,%1,0,48"
51b8fc2c
RK
464 [(set_attr "type" "load,*")])
465
466(define_insn ""
467 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
468 (compare:CC (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r"))
469 (const_int 0)))
470 (clobber (match_scratch:DI 2 "=r"))]
471 "TARGET_POWERPC64"
4371f8af 472 "rldicl. %2,%1,0,48"
51b8fc2c
RK
473 [(set_attr "type" "compare")])
474
475(define_insn ""
476 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
477 (compare:CC (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r"))
478 (const_int 0)))
479 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
480 (zero_extend:DI (match_dup 1)))]
481 "TARGET_POWERPC64"
4371f8af 482 "rldicl. %0,%1,0,48"
51b8fc2c
RK
483 [(set_attr "type" "compare")])
484
485(define_expand "extendhidi2"
486 [(set (match_operand:DI 0 "gpc_reg_operand" "")
487 (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "")))]
488 "TARGET_POWERPC64"
489 "")
490
491(define_insn ""
492 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
493 (sign_extend:DI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
494 "TARGET_POWERPC64"
495 "@
496 lha%U1%X1 %0,%1
497 extsh %0,%1"
498 [(set_attr "type" "load,*")])
499
500(define_insn ""
501 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
502 (compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r"))
503 (const_int 0)))
504 (clobber (match_scratch:DI 2 "=r"))]
505 "TARGET_POWERPC64"
506 "extsh. %2,%1"
507 [(set_attr "type" "compare")])
508
509(define_insn ""
510 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
511 (compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r"))
512 (const_int 0)))
513 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
514 (sign_extend:DI (match_dup 1)))]
515 "TARGET_POWERPC64"
516 "extsh. %0,%1"
517 [(set_attr "type" "compare")])
518
519(define_expand "zero_extendsidi2"
520 [(set (match_operand:DI 0 "gpc_reg_operand" "")
521 (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")))]
522 "TARGET_POWERPC64"
523 "")
524
525(define_insn ""
526 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
527 (zero_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "m,r")))]
528 "TARGET_POWERPC64"
529 "@
530 lwz%U1%X1 %0,%1
531 rldicl %0,%1,0,32"
532 [(set_attr "type" "load,*")])
533
534(define_insn ""
535 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
536 (compare:CC (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
537 (const_int 0)))
538 (clobber (match_scratch:DI 2 "=r"))]
539 "TARGET_POWERPC64"
540 "rldicl. %2,%1,0,32"
541 [(set_attr "type" "compare")])
542
543(define_insn ""
544 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
545 (compare:CC (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
546 (const_int 0)))
547 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
548 (zero_extend:DI (match_dup 1)))]
549 "TARGET_POWERPC64"
550 "rldicl. %0,%1,0,32"
551 [(set_attr "type" "compare")])
552
553(define_expand "extendsidi2"
554 [(set (match_operand:DI 0 "gpc_reg_operand" "")
555 (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")))]
556 "TARGET_POWERPC64"
557 "")
558
559(define_insn ""
560 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
287f13ff 561 (sign_extend:DI (match_operand:SI 1 "lwa_operand" "m,r")))]
51b8fc2c
RK
562 "TARGET_POWERPC64"
563 "@
564 lwa%U1%X1 %0,%1
565 extsw %0,%1"
566 [(set_attr "type" "load,*")])
567
568(define_insn ""
569 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
570 (compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
571 (const_int 0)))
572 (clobber (match_scratch:DI 2 "=r"))]
573 "TARGET_POWERPC64"
574 "extsw. %2,%1"
575 [(set_attr "type" "compare")])
576
577(define_insn ""
578 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
579 (compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
580 (const_int 0)))
581 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
582 (sign_extend:DI (match_dup 1)))]
583 "TARGET_POWERPC64"
584 "extsw. %0,%1"
585 [(set_attr "type" "compare")])
586
1fd4e8c1 587(define_expand "zero_extendqisi2"
cd2b37d9
RK
588 [(set (match_operand:SI 0 "gpc_reg_operand" "")
589 (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "")))]
1fd4e8c1
RK
590 ""
591 "")
592
593(define_insn ""
cd2b37d9 594 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
595 (zero_extend:SI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
596 ""
597 "@
598 lbz%U1%X1 %0,%1
005a35b9 599 {rlinm|rlwinm} %0,%1,0,0xff"
1fd4e8c1
RK
600 [(set_attr "type" "load,*")])
601
602(define_insn ""
603 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
cd2b37d9 604 (compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r"))
1fd4e8c1
RK
605 (const_int 0)))
606 (clobber (match_scratch:SI 2 "=r"))]
607 ""
ca7f5001 608 "{andil.|andi.} %2,%1,0xff"
1fd4e8c1
RK
609 [(set_attr "type" "compare")])
610
611(define_insn ""
612 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
cd2b37d9 613 (compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r"))
1fd4e8c1 614 (const_int 0)))
cd2b37d9 615 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
616 (zero_extend:SI (match_dup 1)))]
617 ""
ca7f5001 618 "{andil.|andi.} %0,%1,0xff"
1fd4e8c1
RK
619 [(set_attr "type" "compare")])
620
51b8fc2c
RK
621(define_expand "extendqisi2"
622 [(use (match_operand:SI 0 "gpc_reg_operand" ""))
623 (use (match_operand:QI 1 "gpc_reg_operand" ""))]
624 ""
625 "
626{
627 if (TARGET_POWERPC)
628 emit_insn (gen_extendqisi2_ppc (operands[0], operands[1]));
629 else if (TARGET_POWER)
630 emit_insn (gen_extendqisi2_power (operands[0], operands[1]));
631 else
632 emit_insn (gen_extendqisi2_no_power (operands[0], operands[1]));
633 DONE;
634}")
635
636(define_insn "extendqisi2_ppc"
2bee0449
RK
637 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
638 (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r")))]
51b8fc2c 639 "TARGET_POWERPC"
2bee0449 640 "extsb %0,%1")
51b8fc2c
RK
641
642(define_insn ""
643 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
644 (compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r"))
645 (const_int 0)))
646 (clobber (match_scratch:SI 2 "=r"))]
647 "TARGET_POWERPC"
648 "extsb. %2,%1"
649 [(set_attr "type" "compare")])
650
651(define_insn ""
652 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
653 (compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r"))
654 (const_int 0)))
655 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
656 (sign_extend:SI (match_dup 1)))]
657 "TARGET_POWERPC"
658 "extsb. %0,%1"
659 [(set_attr "type" "compare")])
660
661(define_expand "extendqisi2_power"
662 [(parallel [(set (match_dup 2)
663 (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "")
664 (const_int 24)))
665 (clobber (scratch:SI))])
666 (parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
667 (ashiftrt:SI (match_dup 2)
668 (const_int 24)))
669 (clobber (scratch:SI))])]
670 "TARGET_POWER"
671 "
672{ operands[1] = gen_lowpart (SImode, operands[1]);
673 operands[2] = gen_reg_rtx (SImode); }")
674
675(define_expand "extendqisi2_no_power"
676 [(set (match_dup 2)
677 (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "")
678 (const_int 24)))
679 (set (match_operand:SI 0 "gpc_reg_operand" "")
680 (ashiftrt:SI (match_dup 2)
681 (const_int 24)))]
682 "! TARGET_POWER && ! TARGET_POWERPC"
683 "
684{ operands[1] = gen_lowpart (SImode, operands[1]);
685 operands[2] = gen_reg_rtx (SImode); }")
686
1fd4e8c1 687(define_expand "zero_extendqihi2"
cd2b37d9
RK
688 [(set (match_operand:HI 0 "gpc_reg_operand" "")
689 (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "")))]
1fd4e8c1
RK
690 ""
691 "")
692
693(define_insn ""
cd2b37d9 694 [(set (match_operand:HI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
695 (zero_extend:HI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
696 ""
697 "@
698 lbz%U1%X1 %0,%1
005a35b9 699 {rlinm|rlwinm} %0,%1,0,0xff"
51b8fc2c
RK
700 [(set_attr "type" "load,*")])
701
702(define_insn ""
703 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
704 (compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r"))
705 (const_int 0)))
706 (clobber (match_scratch:HI 2 "=r"))]
707 ""
708 "{andil.|andi.} %2,%1,0xff"
709 [(set_attr "type" "compare")])
710
711(define_insn ""
712 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
713 (compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r"))
714 (const_int 0)))
715 (set (match_operand:HI 0 "gpc_reg_operand" "=r")
716 (zero_extend:HI (match_dup 1)))]
717 ""
718 "{andil.|andi.} %0,%1,0xff"
719 [(set_attr "type" "compare")])
720
721(define_expand "extendqihi2"
722 [(use (match_operand:HI 0 "gpc_reg_operand" ""))
723 (use (match_operand:QI 1 "gpc_reg_operand" ""))]
724 ""
725 "
726{
727 if (TARGET_POWERPC)
728 emit_insn (gen_extendqihi2_ppc (operands[0], operands[1]));
729 else if (TARGET_POWER)
730 emit_insn (gen_extendqihi2_power (operands[0], operands[1]));
731 else
732 emit_insn (gen_extendqihi2_no_power (operands[0], operands[1]));
733 DONE;
734}")
735
736(define_insn "extendqihi2_ppc"
2bee0449
RK
737 [(set (match_operand:HI 0 "gpc_reg_operand" "=r")
738 (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r")))]
51b8fc2c 739 "TARGET_POWERPC"
2bee0449 740 "extsb %0,%1")
1fd4e8c1 741
51b8fc2c
RK
742(define_insn ""
743 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
744 (compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r"))
745 (const_int 0)))
746 (clobber (match_scratch:HI 2 "=r"))]
747 "TARGET_POWERPC"
748 "extsb. %2,%1"
749 [(set_attr "type" "compare")])
750
751(define_insn ""
752 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
753 (compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r"))
754 (const_int 0)))
755 (set (match_operand:HI 0 "gpc_reg_operand" "=r")
756 (sign_extend:HI (match_dup 1)))]
757 "TARGET_POWERPC"
758 "extsb. %0,%1"
759 [(set_attr "type" "compare")])
760
761(define_expand "extendqihi2_power"
762 [(parallel [(set (match_dup 2)
763 (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "")
764 (const_int 24)))
765 (clobber (scratch:SI))])
766 (parallel [(set (match_operand:HI 0 "gpc_reg_operand" "")
767 (ashiftrt:SI (match_dup 2)
768 (const_int 24)))
769 (clobber (scratch:SI))])]
770 "TARGET_POWER"
771 "
772{ operands[0] = gen_lowpart (SImode, operands[0]);
773 operands[1] = gen_lowpart (SImode, operands[1]);
774 operands[2] = gen_reg_rtx (SImode); }")
775
776(define_expand "extendqihi2_no_power"
777 [(set (match_dup 2)
778 (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "")
779 (const_int 24)))
780 (set (match_operand:HI 0 "gpc_reg_operand" "")
781 (ashiftrt:SI (match_dup 2)
782 (const_int 24)))]
783 "! TARGET_POWER && ! TARGET_POWERPC"
784 "
785{ operands[0] = gen_lowpart (SImode, operands[0]);
786 operands[1] = gen_lowpart (SImode, operands[1]);
787 operands[2] = gen_reg_rtx (SImode); }")
788
1fd4e8c1 789(define_expand "zero_extendhisi2"
5f243543 790 [(set (match_operand:SI 0 "gpc_reg_operand" "")
cd2b37d9 791 (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")))]
1fd4e8c1
RK
792 ""
793 "")
794
795(define_insn ""
cd2b37d9 796 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
797 (zero_extend:SI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
798 ""
799 "@
800 lhz%U1%X1 %0,%1
005a35b9 801 {rlinm|rlwinm} %0,%1,0,0xffff"
1fd4e8c1
RK
802 [(set_attr "type" "load,*")])
803
804(define_insn ""
805 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
cd2b37d9 806 (compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r"))
1fd4e8c1
RK
807 (const_int 0)))
808 (clobber (match_scratch:SI 2 "=r"))]
809 ""
ca7f5001 810 "{andil.|andi.} %2,%1,0xffff"
1fd4e8c1
RK
811 [(set_attr "type" "compare")])
812
813(define_insn ""
814 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
cd2b37d9 815 (compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r"))
1fd4e8c1 816 (const_int 0)))
cd2b37d9 817 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
818 (zero_extend:SI (match_dup 1)))]
819 ""
ca7f5001 820 "{andil.|andi.} %0,%1,0xffff"
1fd4e8c1
RK
821 [(set_attr "type" "compare")])
822
823(define_expand "extendhisi2"
cd2b37d9
RK
824 [(set (match_operand:SI 0 "gpc_reg_operand" "")
825 (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")))]
1fd4e8c1
RK
826 ""
827 "")
828
829(define_insn ""
cd2b37d9 830 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
831 (sign_extend:SI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
832 ""
833 "@
834 lha%U1%X1 %0,%1
ca7f5001 835 {exts|extsh} %0,%1"
1fd4e8c1
RK
836 [(set_attr "type" "load,*")])
837
838(define_insn ""
839 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
cd2b37d9 840 (compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r"))
1fd4e8c1
RK
841 (const_int 0)))
842 (clobber (match_scratch:SI 2 "=r"))]
843 ""
ca7f5001 844 "{exts.|extsh.} %2,%1"
1fd4e8c1
RK
845 [(set_attr "type" "compare")])
846
847(define_insn ""
848 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
cd2b37d9 849 (compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r"))
1fd4e8c1 850 (const_int 0)))
cd2b37d9 851 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
852 (sign_extend:SI (match_dup 1)))]
853 ""
ca7f5001 854 "{exts.|extsh.} %0,%1"
1fd4e8c1
RK
855 [(set_attr "type" "compare")])
856\f
857;; Fixed-point arithmetic insns.
deb9225a
RK
858
859;; Discourage ai/addic because of carry but provide it in an alternative
860;; allowing register zero as source.
7cd5235b
MM
861(define_expand "addsi3"
862 [(set (match_operand:SI 0 "gpc_reg_operand" "")
863 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "")
864 (match_operand:SI 2 "reg_or_cint_operand" "")))]
865 ""
866 "
867{
868 if (GET_CODE (operands[2]) == CONST_INT && !add_operand (operands[2], SImode))
869 {
870 rtx tmp = ((reload_in_progress || reload_completed
871 || rtx_equal_p (operands[0], operands[1]))
872 ? operands[0] : gen_reg_rtx (SImode));
873
874 HOST_WIDE_INT low = INTVAL (operands[2]) & 0xffff;
875 HOST_WIDE_INT high = INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff);
876
877 if (low & 0x8000)
878 high += 0x10000, low |= ((HOST_WIDE_INT) -1) << 16;
879
880 emit_insn (gen_addsi3 (tmp, operands[1], GEN_INT (high)));
881 emit_insn (gen_addsi3 (operands[0], tmp, GEN_INT (low)));
882 DONE;
883 }
884}")
885
886(define_insn "*addsi3_internal1"
887 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,?r,r")
888 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "%r,b,r,b")
889 (match_operand:SI 2 "add_operand" "r,I,I,J")))]
1fd4e8c1
RK
890 ""
891 "@
deb9225a
RK
892 {cax|add} %0,%1,%2
893 {cal %0,%2(%1)|addi %0,%1,%2}
894 {ai|addic} %0,%1,%2
7cd5235b
MM
895 {cau|addis} %0,%1,%v2"
896 [(set_attr "length" "4,4,4,4")])
1fd4e8c1 897
7cd5235b 898(define_insn "*addsi3_internal2"
deb9225a
RK
899 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
900 (compare:CC (plus:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
901 (match_operand:SI 2 "reg_or_short_operand" "r,I"))
1fd4e8c1 902 (const_int 0)))
deb9225a 903 (clobber (match_scratch:SI 3 "=r,r"))]
1fd4e8c1 904 ""
deb9225a
RK
905 "@
906 {cax.|add.} %3,%1,%2
907 {ai.|addic.} %3,%1,%2"
1fd4e8c1 908 [(set_attr "type" "compare")])
7e69e155 909
7cd5235b 910(define_insn "*addsi3_internal3"
deb9225a
RK
911 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
912 (compare:CC (plus:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
913 (match_operand:SI 2 "reg_or_short_operand" "r,I"))
1fd4e8c1 914 (const_int 0)))
deb9225a 915 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
916 (plus:SI (match_dup 1) (match_dup 2)))]
917 ""
deb9225a
RK
918 "@
919 {cax.|add.} %0,%1,%2
920 {ai.|addic.} %0,%1,%2"
1fd4e8c1 921 [(set_attr "type" "compare")])
7e69e155 922
f357808b
RK
923;; Split an add that we can't do in one insn into two insns, each of which
924;; does one 16-bit part. This is used by combine. Note that the low-order
925;; add should be last in case the result gets used in an address.
926
927(define_split
cd2b37d9
RK
928 [(set (match_operand:SI 0 "gpc_reg_operand" "")
929 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "")
f357808b 930 (match_operand:SI 2 "non_add_cint_operand" "")))]
1fd4e8c1 931 ""
f357808b
RK
932 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))
933 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))]
934"
1fd4e8c1 935{
e6ca2c17
DE
936 HOST_WIDE_INT low = INTVAL (operands[2]) & 0xffff;
937 HOST_WIDE_INT high = INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff);
1fd4e8c1 938
f357808b 939 if (low & 0x8000)
e6ca2c17 940 high += 0x10000, low |= ((HOST_WIDE_INT) -1) << 16;
1fd4e8c1 941
e6ca2c17
DE
942 operands[3] = GEN_INT (high);
943 operands[4] = GEN_INT (low);
1fd4e8c1
RK
944}")
945
8de2a197 946(define_insn "one_cmplsi2"
cd2b37d9
RK
947 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
948 (not:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
1fd4e8c1 949 ""
ca7f5001
RK
950 "nor %0,%1,%1")
951
952(define_insn ""
953 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
954 (compare:CC (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
955 (const_int 0)))
956 (clobber (match_scratch:SI 2 "=r"))]
957 ""
958 "nor. %2,%1,%1"
959 [(set_attr "type" "compare")])
960
961(define_insn ""
8de2a197 962 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
ca7f5001
RK
963 (compare:CC (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
964 (const_int 0)))
965 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
966 (not:SI (match_dup 1)))]
967 ""
d944f453 968 "nor. %0,%1,%1"
ca7f5001 969 [(set_attr "type" "compare")])
1fd4e8c1
RK
970
971(define_insn ""
3d91674b
RK
972 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
973 (minus:SI (match_operand:SI 1 "reg_or_short_operand" "rI")
974 (match_operand:SI 2 "gpc_reg_operand" "r")))]
deb9225a 975 "! TARGET_POWERPC"
ca7f5001 976 "{sf%I1|subf%I1c} %0,%2,%1")
1fd4e8c1 977
deb9225a
RK
978(define_insn ""
979 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
980 (minus:SI (match_operand:SI 1 "reg_or_short_operand" "r,I")
981 (match_operand:SI 2 "gpc_reg_operand" "r,r")))]
982 "TARGET_POWERPC"
983 "@
984 subf %0,%2,%1
985 subfic %0,%2,%1")
986
1fd4e8c1
RK
987(define_insn ""
988 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
cd2b37d9
RK
989 (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
990 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1
RK
991 (const_int 0)))
992 (clobber (match_scratch:SI 3 "=r"))]
deb9225a 993 "! TARGET_POWERPC"
ca7f5001 994 "{sf.|subfc.} %3,%2,%1"
1fd4e8c1
RK
995 [(set_attr "type" "compare")])
996
deb9225a
RK
997(define_insn ""
998 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
999 (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1000 (match_operand:SI 2 "gpc_reg_operand" "r"))
1001 (const_int 0)))
1002 (clobber (match_scratch:SI 3 "=r"))]
1003 "TARGET_POWERPC"
1004 "subf. %3,%2,%1"
1005 [(set_attr "type" "compare")])
1006
1fd4e8c1
RK
1007(define_insn ""
1008 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
cd2b37d9
RK
1009 (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1010 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 1011 (const_int 0)))
cd2b37d9 1012 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1 1013 (minus:SI (match_dup 1) (match_dup 2)))]
deb9225a 1014 "! TARGET_POWERPC"
ca7f5001 1015 "{sf.|subfc.} %0,%2,%1"
1fd4e8c1
RK
1016 [(set_attr "type" "compare")])
1017
deb9225a
RK
1018(define_insn ""
1019 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1020 (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1021 (match_operand:SI 2 "gpc_reg_operand" "r"))
1022 (const_int 0)))
1023 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1024 (minus:SI (match_dup 1) (match_dup 2)))]
1025 "TARGET_POWERPC"
1026 "subf. %0,%2,%1"
1027 [(set_attr "type" "compare")])
1028
1fd4e8c1 1029(define_expand "subsi3"
cd2b37d9 1030 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
1031 (minus:SI (match_operand:SI 1 "reg_or_short_operand" "")
1032 (match_operand:SI 2 "reg_or_cint_operand" "")))]
1033 ""
a0044fb1
RK
1034 "
1035{
1036 if (GET_CODE (operands[2]) == CONST_INT)
1037 {
1038 emit_insn (gen_addsi3 (operands[0], operands[1],
1039 negate_rtx (SImode, operands[2])));
1040 DONE;
1041 }
1042}")
1fd4e8c1
RK
1043
1044;; For SMIN, SMAX, UMIN, and UMAX, we use DEFINE_EXPAND's that involve a doz[i]
1045;; instruction and some auxiliary computations. Then we just have a single
95ac8e67
RK
1046;; DEFINE_INSN for doz[i] and the define_splits to make them if made by
1047;; combine.
1fd4e8c1
RK
1048
1049(define_expand "sminsi3"
1050 [(set (match_dup 3)
cd2b37d9 1051 (if_then_else:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1
RK
1052 (match_operand:SI 2 "reg_or_short_operand" ""))
1053 (const_int 0)
1054 (minus:SI (match_dup 2) (match_dup 1))))
cd2b37d9 1055 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1 1056 (minus:SI (match_dup 2) (match_dup 3)))]
ca7f5001 1057 "TARGET_POWER"
1fd4e8c1
RK
1058 "
1059{ operands[3] = gen_reg_rtx (SImode); }")
1060
95ac8e67
RK
1061(define_split
1062 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1063 (smin:SI (match_operand:SI 1 "gpc_reg_operand" "")
1064 (match_operand:SI 2 "reg_or_short_operand" "")))
1065 (clobber (match_operand:SI 3 "gpc_reg_operand" ""))]
ca7f5001 1066 "TARGET_POWER"
95ac8e67
RK
1067 [(set (match_dup 3)
1068 (if_then_else:SI (gt:SI (match_dup 1) (match_dup 2))
1069 (const_int 0)
1070 (minus:SI (match_dup 2) (match_dup 1))))
1071 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 3)))]
1072 "")
1073
1fd4e8c1
RK
1074(define_expand "smaxsi3"
1075 [(set (match_dup 3)
cd2b37d9 1076 (if_then_else:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1
RK
1077 (match_operand:SI 2 "reg_or_short_operand" ""))
1078 (const_int 0)
1079 (minus:SI (match_dup 2) (match_dup 1))))
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
RK
1083 "
1084{ operands[3] = gen_reg_rtx (SImode); }")
1085
95ac8e67
RK
1086(define_split
1087 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1088 (smax:SI (match_operand:SI 1 "gpc_reg_operand" "")
1089 (match_operand:SI 2 "reg_or_short_operand" "")))
1090 (clobber (match_operand:SI 3 "gpc_reg_operand" ""))]
ca7f5001 1091 "TARGET_POWER"
95ac8e67
RK
1092 [(set (match_dup 3)
1093 (if_then_else:SI (gt:SI (match_dup 1) (match_dup 2))
1094 (const_int 0)
1095 (minus:SI (match_dup 2) (match_dup 1))))
1096 (set (match_dup 0) (plus:SI (match_dup 3) (match_dup 1)))]
1097 "")
1098
1fd4e8c1 1099(define_expand "uminsi3"
cd2b37d9 1100 [(set (match_dup 3) (xor:SI (match_operand:SI 1 "gpc_reg_operand" "")
bb68ff55 1101 (match_dup 5)))
cd2b37d9 1102 (set (match_dup 4) (xor:SI (match_operand:SI 2 "gpc_reg_operand" "")
bb68ff55 1103 (match_dup 5)))
1fd4e8c1
RK
1104 (set (match_dup 3) (if_then_else:SI (gt (match_dup 3) (match_dup 4))
1105 (const_int 0)
1106 (minus:SI (match_dup 4) (match_dup 3))))
cd2b37d9 1107 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1 1108 (minus:SI (match_dup 2) (match_dup 3)))]
ca7f5001 1109 "TARGET_POWER"
1fd4e8c1 1110 "
bb68ff55
MM
1111{
1112 operands[3] = gen_reg_rtx (SImode);
1113 operands[4] = gen_reg_rtx (SImode);
1114 operands[5] = GEN_INT (-2147483647 - 1);
1115}")
1fd4e8c1
RK
1116
1117(define_expand "umaxsi3"
cd2b37d9 1118 [(set (match_dup 3) (xor:SI (match_operand:SI 1 "gpc_reg_operand" "")
bb68ff55 1119 (match_dup 5)))
cd2b37d9 1120 (set (match_dup 4) (xor:SI (match_operand:SI 2 "gpc_reg_operand" "")
bb68ff55 1121 (match_dup 5)))
1fd4e8c1
RK
1122 (set (match_dup 3) (if_then_else:SI (gt (match_dup 3) (match_dup 4))
1123 (const_int 0)
1124 (minus:SI (match_dup 4) (match_dup 3))))
cd2b37d9 1125 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1 1126 (plus:SI (match_dup 3) (match_dup 1)))]
ca7f5001 1127 "TARGET_POWER"
1fd4e8c1 1128 "
bb68ff55
MM
1129{
1130 operands[3] = gen_reg_rtx (SImode);
1131 operands[4] = gen_reg_rtx (SImode);
1132 operands[5] = GEN_INT (-2147483647 - 1);
1133}")
1fd4e8c1
RK
1134
1135(define_insn ""
cd2b37d9
RK
1136 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1137 (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "r")
5c23c401 1138 (match_operand:SI 2 "reg_or_short_operand" "rI"))
1fd4e8c1
RK
1139 (const_int 0)
1140 (minus:SI (match_dup 2) (match_dup 1))))]
ca7f5001 1141 "TARGET_POWER"
1fd4e8c1
RK
1142 "doz%I2 %0,%1,%2")
1143
1144(define_insn ""
1145 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1146 (compare:CC
cd2b37d9 1147 (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "r")
5c23c401 1148 (match_operand:SI 2 "reg_or_short_operand" "rI"))
1fd4e8c1
RK
1149 (const_int 0)
1150 (minus:SI (match_dup 2) (match_dup 1)))
1151 (const_int 0)))
1152 (clobber (match_scratch:SI 3 "=r"))]
ca7f5001 1153 "TARGET_POWER"
1fd4e8c1
RK
1154 "doz%I2. %3,%1,%2"
1155 [(set_attr "type" "delayed_compare")])
1156
1157(define_insn ""
1158 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1159 (compare:CC
cd2b37d9 1160 (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "r")
5c23c401 1161 (match_operand:SI 2 "reg_or_short_operand" "rI"))
1fd4e8c1
RK
1162 (const_int 0)
1163 (minus:SI (match_dup 2) (match_dup 1)))
1164 (const_int 0)))
cd2b37d9 1165 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
1166 (if_then_else:SI (gt (match_dup 1) (match_dup 2))
1167 (const_int 0)
1168 (minus:SI (match_dup 2) (match_dup 1))))]
ca7f5001 1169 "TARGET_POWER"
1fd4e8c1
RK
1170 "doz%I2. %0,%1,%2"
1171 [(set_attr "type" "delayed_compare")])
1172
1173;; We don't need abs with condition code because such comparisons should
1174;; never be done.
ea9be077
MM
1175(define_expand "abssi2"
1176 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1177 (abs:SI (match_operand:SI 1 "gpc_reg_operand" "")))]
1178 ""
1179 "
1180{
1181 if (!TARGET_POWER)
1182 {
1183 emit_insn (gen_abssi2_nopower (operands[0], operands[1]));
1184 DONE;
1185 }
1186}")
1187
1188(define_insn "abssi2_power"
cd2b37d9
RK
1189 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1190 (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
ca7f5001 1191 "TARGET_POWER"
1fd4e8c1
RK
1192 "abs %0,%1")
1193
ea9be077
MM
1194(define_insn "abssi2_nopower"
1195 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r")
1196 (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0")))
1197 (clobber (match_scratch:SI 2 "=&r,&r"))]
1198 "!TARGET_POWER"
3595d104
MM
1199 "*
1200{
1201 return (TARGET_POWERPC)
1202 ? \"{srai|srawi} %2,%1,31\;xor %0,%2,%1\;subf %0,%2,%0\"
1203 : \"{srai|srawi} %2,%1,31\;xor %0,%2,%1\;{sf|subfc} %0,%2,%0\";
1204}"
ea9be077
MM
1205 [(set_attr "length" "12")])
1206
1207(define_split
1208 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r")
1209 (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0")))
1210 (clobber (match_scratch:SI 2 "=&r,&r"))]
1211 "!TARGET_POWER && reload_completed"
1212 [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31)))
1213 (set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))
7093ddee 1214 (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 2)))]
ea9be077
MM
1215 "")
1216
1fd4e8c1 1217(define_insn ""
cd2b37d9
RK
1218 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1219 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r"))))]
ca7f5001 1220 "TARGET_POWER"
1fd4e8c1
RK
1221 "nabs %0,%1")
1222
ea9be077
MM
1223(define_insn ""
1224 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r")
1225 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0"))))
1226 (clobber (match_scratch:SI 2 "=&r,&r"))]
1227 "!TARGET_POWER"
3595d104
MM
1228 "*
1229{
1230 return (TARGET_POWERPC)
1231 ? \"{srai|srawi} %2,%1,31\;xor %0,%2,%1\;subf %0,%0,%2\"
1232 : \"{srai|srawi} %2,%1,31\;xor %0,%2,%1\;{sf|subfc} %0,%0,%2\";
1233}"
ea9be077
MM
1234 [(set_attr "length" "12")])
1235
1236(define_split
1237 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r")
1238 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0"))))
1239 (clobber (match_scratch:SI 2 "=&r,&r"))]
1240 "!TARGET_POWER && reload_completed"
1241 [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31)))
1242 (set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))
7093ddee 1243 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 0)))]
ea9be077
MM
1244 "")
1245
1fd4e8c1 1246(define_insn "negsi2"
cd2b37d9
RK
1247 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1248 (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
1fd4e8c1
RK
1249 ""
1250 "neg %0,%1")
1251
1252(define_insn ""
1253 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
cd2b37d9 1254 (compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1fd4e8c1
RK
1255 (const_int 0)))
1256 (clobber (match_scratch:SI 2 "=r"))]
1257 ""
1258 "neg. %2,%1"
1259 [(set_attr "type" "compare")])
1260
1261(define_insn ""
1262 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
cd2b37d9 1263 (compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1fd4e8c1 1264 (const_int 0)))
cd2b37d9 1265 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
1266 (neg:SI (match_dup 1)))]
1267 ""
1268 "neg. %0,%1"
1269 [(set_attr "type" "compare")])
1270
1271(define_insn "ffssi2"
242e8072
RK
1272 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r")
1273 (ffs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
1fd4e8c1 1274 ""
7f340546 1275 "neg %0,%1\;and %0,%0,%1\;{cntlz|cntlzw} %0,%0\;{sfi|subfic} %0,%0,32"
b19003d8 1276 [(set_attr "length" "16")])
1fd4e8c1 1277
ca7f5001
RK
1278(define_expand "mulsi3"
1279 [(use (match_operand:SI 0 "gpc_reg_operand" ""))
1280 (use (match_operand:SI 1 "gpc_reg_operand" ""))
1281 (use (match_operand:SI 2 "reg_or_short_operand" ""))]
1282 ""
1283 "
1284{
1285 if (TARGET_POWER)
68b40e7e 1286 emit_insn (gen_mulsi3_mq (operands[0], operands[1], operands[2]));
ca7f5001 1287 else
68b40e7e 1288 emit_insn (gen_mulsi3_no_mq (operands[0], operands[1], operands[2]));
ca7f5001
RK
1289 DONE;
1290}")
1291
68b40e7e 1292(define_insn "mulsi3_mq"
cd2b37d9
RK
1293 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1294 (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
1fd4e8c1
RK
1295 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
1296 (clobber (match_scratch:SI 3 "=q,q"))]
ca7f5001
RK
1297 "TARGET_POWER"
1298 "@
1299 {muls|mullw} %0,%1,%2
1300 {muli|mulli} %0,%1,%2"
1301 [(set_attr "type" "imul")])
1302
68b40e7e 1303(define_insn "mulsi3_no_mq"
ca7f5001
RK
1304 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1305 (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
1306 (match_operand:SI 2 "reg_or_short_operand" "r,I")))]
68b40e7e 1307 "! TARGET_POWER"
1fd4e8c1 1308 "@
d904e9ed
RK
1309 {muls|mullw} %0,%1,%2
1310 {muli|mulli} %0,%1,%2"
cfb557c4 1311 [(set_attr "type" "imul")])
1fd4e8c1
RK
1312
1313(define_insn ""
1314 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
deb9225a 1315 (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
cd2b37d9 1316 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1
RK
1317 (const_int 0)))
1318 (clobber (match_scratch:SI 3 "=r"))
1319 (clobber (match_scratch:SI 4 "=q"))]
ca7f5001
RK
1320 "TARGET_POWER"
1321 "{muls.|mullw.} %3,%1,%2"
1322 [(set_attr "type" "delayed_compare")])
1323
1324(define_insn ""
1325 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
deb9225a 1326 (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
ca7f5001
RK
1327 (match_operand:SI 2 "gpc_reg_operand" "r"))
1328 (const_int 0)))
1329 (clobber (match_scratch:SI 3 "=r"))]
25c341fa 1330 "! TARGET_POWER"
d904e9ed 1331 "{muls.|mullw.} %3,%1,%2"
1fd4e8c1
RK
1332 [(set_attr "type" "delayed_compare")])
1333
1334(define_insn ""
1335 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
deb9225a 1336 (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
cd2b37d9 1337 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 1338 (const_int 0)))
cd2b37d9 1339 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
1340 (mult:SI (match_dup 1) (match_dup 2)))
1341 (clobber (match_scratch:SI 4 "=q"))]
ca7f5001
RK
1342 "TARGET_POWER"
1343 "{muls.|mullw.} %0,%1,%2"
1344 [(set_attr "type" "delayed_compare")])
1345
1346(define_insn ""
1347 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
deb9225a 1348 (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
ca7f5001
RK
1349 (match_operand:SI 2 "gpc_reg_operand" "r"))
1350 (const_int 0)))
1351 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1352 (mult:SI (match_dup 1) (match_dup 2)))]
25c341fa 1353 "! TARGET_POWER"
d904e9ed 1354 "{muls.|mullw.} %0,%1,%2"
1fd4e8c1
RK
1355 [(set_attr "type" "delayed_compare")])
1356
1357;; Operand 1 is divided by operand 2; quotient goes to operand
1358;; 0 and remainder to operand 3.
1359;; ??? At some point, see what, if anything, we can do about if (x % y == 0).
1360
8ffd9c51
RK
1361(define_expand "divmodsi4"
1362 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
1363 (div:SI (match_operand:SI 1 "gpc_reg_operand" "")
1364 (match_operand:SI 2 "gpc_reg_operand" "")))
1365 (set (match_operand:SI 3 "gpc_reg_operand" "")
1366 (mod:SI (match_dup 1) (match_dup 2)))])]
1367 "TARGET_POWER || (! TARGET_POWER && ! TARGET_POWERPC)"
1368 "
1369{
1370 if (! TARGET_POWER && ! TARGET_POWERPC)
1371 {
1372 emit_move_insn (gen_rtx (REG, SImode, 3), operands[1]);
1373 emit_move_insn (gen_rtx (REG, SImode, 4), operands[2]);
fada905b 1374 emit_insn (gen_divss_call ());
8ffd9c51
RK
1375 emit_move_insn (operands[0], gen_rtx (REG, SImode, 3));
1376 emit_move_insn (operands[3], gen_rtx (REG, SImode, 4));
1377 DONE;
1378 }
1379}")
deb9225a 1380
fada905b 1381(define_insn ""
cd2b37d9
RK
1382 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1383 (div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1384 (match_operand:SI 2 "gpc_reg_operand" "r")))
1385 (set (match_operand:SI 3 "gpc_reg_operand" "=q")
1fd4e8c1 1386 (mod:SI (match_dup 1) (match_dup 2)))]
ca7f5001 1387 "TARGET_POWER"
cfb557c4
RK
1388 "divs %0,%1,%2"
1389 [(set_attr "type" "idiv")])
1fd4e8c1 1390
8ffd9c51
RK
1391(define_expand "udivsi3"
1392 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1393 (udiv:SI (match_operand:SI 1 "gpc_reg_operand" "")
1394 (match_operand:SI 2 "gpc_reg_operand" "")))]
1395 "TARGET_POWERPC || (! TARGET_POWER && ! TARGET_POWERPC)"
1396 "
1397{
1398 if (! TARGET_POWER && ! TARGET_POWERPC)
1399 {
1400 emit_move_insn (gen_rtx (REG, SImode, 3), operands[1]);
1401 emit_move_insn (gen_rtx (REG, SImode, 4), operands[2]);
fada905b 1402 emit_insn (gen_quous_call ());
8ffd9c51
RK
1403 emit_move_insn (operands[0], gen_rtx (REG, SImode, 3));
1404 DONE;
1405 }
f192bf8b
DE
1406 else if (TARGET_POWER)
1407 {
1408 emit_insn (gen_udivsi3_mq (operands[0], operands[1], operands[2]));
1409 DONE;
1410 }
8ffd9c51 1411}")
deb9225a 1412
f192bf8b
DE
1413(define_insn "udivsi3_mq"
1414 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1415 (udiv:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1416 (match_operand:SI 2 "gpc_reg_operand" "r")))
1417 (clobber (match_scratch:SI 3 "=q"))]
1418 "TARGET_POWERPC && TARGET_POWER"
1419 "divwu %0,%1,%2"
1420 [(set_attr "type" "idiv")])
1421
1422(define_insn "*udivsi3_no_mq"
ca7f5001
RK
1423 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1424 (udiv:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1425 (match_operand:SI 2 "gpc_reg_operand" "r")))]
f192bf8b 1426 "TARGET_POWERPC && ! TARGET_POWER"
a473029f 1427 "divwu %0,%1,%2"
ca7f5001
RK
1428 [(set_attr "type" "idiv")])
1429
1fd4e8c1 1430;; For powers of two we can do srai/aze for divide and then adjust for
ca7f5001 1431;; modulus. If it isn't a power of two, FAIL on POWER so divmodsi4 will be
8ffd9c51
RK
1432;; used; for PowerPC, force operands into register and do a normal divide;
1433;; for AIX common-mode, use quoss call on register operands.
1fd4e8c1 1434(define_expand "divsi3"
cd2b37d9
RK
1435 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1436 (div:SI (match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1
RK
1437 (match_operand:SI 2 "reg_or_cint_operand" "")))]
1438 ""
1439 "
1440{
ca7f5001
RK
1441 if (GET_CODE (operands[2]) == CONST_INT
1442 && exact_log2 (INTVAL (operands[2])) >= 0)
1443 ;
b6c9286a 1444 else if (TARGET_POWERPC)
f192bf8b
DE
1445 {
1446 operands[2] = force_reg (SImode, operands[2]);
1447 if (TARGET_POWER)
1448 {
1449 emit_insn (gen_divsi3_mq (operands[0], operands[1], operands[2]));
1450 DONE;
1451 }
1452 }
b6c9286a 1453 else if (TARGET_POWER)
1fd4e8c1 1454 FAIL;
405c5495 1455 else
8ffd9c51
RK
1456 {
1457 emit_move_insn (gen_rtx (REG, SImode, 3), operands[1]);
1458 emit_move_insn (gen_rtx (REG, SImode, 4), operands[2]);
fada905b 1459 emit_insn (gen_quoss_call ());
8ffd9c51
RK
1460 emit_move_insn (operands[0], gen_rtx (REG, SImode, 3));
1461 DONE;
1462 }
1fd4e8c1
RK
1463}")
1464
f192bf8b
DE
1465(define_insn "divsi3_mq"
1466 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1467 (div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1468 (match_operand:SI 2 "gpc_reg_operand" "r")))
1469 (clobber (match_scratch:SI 3 "=q"))]
1470 "TARGET_POWERPC && TARGET_POWER"
1471 "divw %0,%1,%2"
1472 [(set_attr "type" "idiv")])
1473
1474(define_insn "*divsi3_no_mq"
1475 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1476 (div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1477 (match_operand:SI 2 "gpc_reg_operand" "r")))]
1478 "TARGET_POWERPC && ! TARGET_POWER"
1479 "divw %0,%1,%2"
1480 [(set_attr "type" "idiv")])
1481
1fd4e8c1 1482(define_expand "modsi3"
85644414
RK
1483 [(use (match_operand:SI 0 "gpc_reg_operand" ""))
1484 (use (match_operand:SI 1 "gpc_reg_operand" ""))
405c5495 1485 (use (match_operand:SI 2 "reg_or_cint_operand" ""))]
39b52ba2 1486 ""
1fd4e8c1
RK
1487 "
1488{
39b52ba2
RK
1489 int i = exact_log2 (INTVAL (operands[2]));
1490 rtx temp1;
1491 rtx temp2;
1492
405c5495 1493 if (GET_CODE (operands[2]) != CONST_INT || i < 0)
39b52ba2
RK
1494 FAIL;
1495
1496 temp1 = gen_reg_rtx (SImode);
1497 temp2 = gen_reg_rtx (SImode);
1fd4e8c1 1498
85644414 1499 emit_insn (gen_divsi3 (temp1, operands[1], operands[2]));
39b52ba2 1500 emit_insn (gen_ashlsi3 (temp2, temp1, GEN_INT (i)));
85644414
RK
1501 emit_insn (gen_subsi3 (operands[0], operands[1], temp2));
1502 DONE;
1fd4e8c1
RK
1503}")
1504
1505(define_insn ""
cd2b37d9
RK
1506 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1507 (div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
1508 (match_operand:SI 2 "const_int_operand" "N")))]
1509 "exact_log2 (INTVAL (operands[2])) >= 0"
ca7f5001 1510 "{srai|srawi} %0,%1,%p2\;{aze|addze} %0,%0"
b19003d8 1511 [(set_attr "length" "8")])
1fd4e8c1
RK
1512
1513(define_insn ""
1514 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
b6b12107
RK
1515 (compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1516 (match_operand:SI 2 "const_int_operand" "N"))
1517 (const_int 0)))
1fd4e8c1
RK
1518 (clobber (match_scratch:SI 3 "=r"))]
1519 "exact_log2 (INTVAL (operands[2])) >= 0"
ca7f5001 1520 "{srai|srawi} %3,%1,%p2\;{aze.|addze.} %3,%3"
b19003d8
RK
1521 [(set_attr "type" "compare")
1522 (set_attr "length" "8")])
1fd4e8c1
RK
1523
1524(define_insn ""
1525 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
b6b12107
RK
1526 (compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1527 (match_operand:SI 2 "const_int_operand" "N"))
1528 (const_int 0)))
cd2b37d9 1529 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
1530 (div:SI (match_dup 1) (match_dup 2)))]
1531 "exact_log2 (INTVAL (operands[2])) >= 0"
ca7f5001 1532 "{srai|srawi} %0,%1,%p2\;{aze.|addze.} %0,%0"
b19003d8
RK
1533 [(set_attr "type" "compare")
1534 (set_attr "length" "8")])
1fd4e8c1
RK
1535
1536(define_insn ""
cd2b37d9 1537 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1 1538 (udiv:SI
996a5f59 1539 (plus:DI (ashift:DI
cd2b37d9 1540 (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
1fd4e8c1 1541 (const_int 32))
23a900dc 1542 (zero_extend:DI (match_operand:SI 4 "register_operand" "2")))
cd2b37d9 1543 (match_operand:SI 3 "gpc_reg_operand" "r")))
740ab4a2 1544 (set (match_operand:SI 2 "register_operand" "=*q")
1fd4e8c1 1545 (umod:SI
996a5f59 1546 (plus:DI (ashift:DI
1fd4e8c1 1547 (zero_extend:DI (match_dup 1)) (const_int 32))
740ab4a2 1548 (zero_extend:DI (match_dup 4)))
1fd4e8c1 1549 (match_dup 3)))]
ca7f5001 1550 "TARGET_POWER"
cfb557c4
RK
1551 "div %0,%1,%3"
1552 [(set_attr "type" "idiv")])
1fd4e8c1
RK
1553
1554;; To do unsigned divide we handle the cases of the divisor looking like a
1555;; negative number. If it is a constant that is less than 2**31, we don't
1556;; have to worry about the branches. So make a few subroutines here.
1557;;
1558;; First comes the normal case.
1559(define_expand "udivmodsi4_normal"
1560 [(set (match_dup 4) (const_int 0))
1561 (parallel [(set (match_operand:SI 0 "" "")
996a5f59 1562 (udiv:SI (plus:DI (ashift:DI (zero_extend:DI (match_dup 4))
1fd4e8c1
RK
1563 (const_int 32))
1564 (zero_extend:DI (match_operand:SI 1 "" "")))
1565 (match_operand:SI 2 "" "")))
1566 (set (match_operand:SI 3 "" "")
996a5f59 1567 (umod:SI (plus:DI (ashift:DI (zero_extend:DI (match_dup 4))
1fd4e8c1
RK
1568 (const_int 32))
1569 (zero_extend:DI (match_dup 1)))
1570 (match_dup 2)))])]
ca7f5001 1571 "TARGET_POWER"
1fd4e8c1
RK
1572 "
1573{ operands[4] = gen_reg_rtx (SImode); }")
1574
1575;; This handles the branches.
1576(define_expand "udivmodsi4_tests"
1577 [(set (match_operand:SI 0 "" "") (const_int 0))
1578 (set (match_operand:SI 3 "" "") (match_operand:SI 1 "" ""))
1579 (set (match_dup 5) (compare:CCUNS (match_dup 1) (match_operand:SI 2 "" "")))
1580 (set (pc) (if_then_else (ltu (match_dup 5) (const_int 0))
1581 (label_ref (match_operand:SI 4 "" "")) (pc)))
1582 (set (match_dup 0) (const_int 1))
1583 (set (match_dup 3) (minus:SI (match_dup 1) (match_dup 2)))
1584 (set (match_dup 6) (compare:CC (match_dup 2) (const_int 0)))
1585 (set (pc) (if_then_else (lt (match_dup 6) (const_int 0))
1586 (label_ref (match_dup 4)) (pc)))]
ca7f5001 1587 "TARGET_POWER"
1fd4e8c1
RK
1588 "
1589{ operands[5] = gen_reg_rtx (CCUNSmode);
1590 operands[6] = gen_reg_rtx (CCmode);
1591}")
1592
1593(define_expand "udivmodsi4"
cd2b37d9
RK
1594 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
1595 (udiv:SI (match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1 1596 (match_operand:SI 2 "reg_or_cint_operand" "")))
cd2b37d9 1597 (set (match_operand:SI 3 "gpc_reg_operand" "")
1fd4e8c1 1598 (umod:SI (match_dup 1) (match_dup 2)))])]
8ffd9c51 1599 ""
1fd4e8c1
RK
1600 "
1601{
1602 rtx label = 0;
1603
8ffd9c51 1604 if (! TARGET_POWER)
c4d38ccb
MM
1605 {
1606 if (! TARGET_POWERPC)
1607 {
1608 emit_move_insn (gen_rtx (REG, SImode, 3), operands[1]);
1609 emit_move_insn (gen_rtx (REG, SImode, 4), operands[2]);
1610 emit_insn (gen_divus_call ());
1611 emit_move_insn (operands[0], gen_rtx (REG, SImode, 3));
1612 emit_move_insn (operands[3], gen_rtx (REG, SImode, 4));
1613 DONE;
1614 }
1615 else
1616 FAIL;
1617 }
0081a354 1618
1fd4e8c1
RK
1619 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) < 0)
1620 {
1621 operands[2] = force_reg (SImode, operands[2]);
1622 label = gen_label_rtx ();
1623 emit (gen_udivmodsi4_tests (operands[0], operands[1], operands[2],
1624 operands[3], label));
1625 }
1626 else
1627 operands[2] = force_reg (SImode, operands[2]);
1628
1629 emit (gen_udivmodsi4_normal (operands[0], operands[1], operands[2],
1630 operands[3]));
1631 if (label)
1632 emit_label (label);
1633
1634 DONE;
1635}")
0081a354 1636
fada905b
MM
1637;; AIX architecture-independent common-mode multiply (DImode),
1638;; divide/modulus, and quotient subroutine calls. Input operands in R3 and
1639;; R4; results in R3 and sometimes R4; link register always clobbered by bla
1640;; instruction; R0 sometimes clobbered; also, MQ sometimes clobbered but
1641;; assumed unused if generating common-mode, so ignore.
1642(define_insn "mulh_call"
1643 [(set (reg:SI 3)
1644 (truncate:SI
1645 (lshiftrt:DI (mult:DI (sign_extend:DI (reg:SI 3))
1646 (sign_extend:DI (reg:SI 4)))
1647 (const_int 32))))
cf27b467 1648 (clobber (match_scratch:SI 0 "=l"))]
fada905b 1649 "! TARGET_POWER && ! TARGET_POWERPC"
b7ff3d82
DE
1650 "bla __mulh"
1651 [(set_attr "type" "imul")])
fada905b
MM
1652
1653(define_insn "mull_call"
1654 [(set (reg:DI 3)
1655 (mult:DI (sign_extend:DI (reg:SI 3))
1656 (sign_extend:DI (reg:SI 4))))
1657 (clobber (match_scratch:SI 0 "=l"))
1658 (clobber (reg:SI 0))]
1659 "! TARGET_POWER && ! TARGET_POWERPC"
b7ff3d82
DE
1660 "bla __mull"
1661 [(set_attr "type" "imul")])
fada905b
MM
1662
1663(define_insn "divss_call"
1664 [(set (reg:SI 3)
1665 (div:SI (reg:SI 3) (reg:SI 4)))
1666 (set (reg:SI 4)
1667 (mod:SI (reg:SI 3) (reg:SI 4)))
1668 (clobber (match_scratch:SI 0 "=l"))
1669 (clobber (reg:SI 0))]
1670 "! TARGET_POWER && ! TARGET_POWERPC"
b7ff3d82
DE
1671 "bla __divss"
1672 [(set_attr "type" "idiv")])
fada905b
MM
1673
1674(define_insn "divus_call"
8ffd9c51
RK
1675 [(set (reg:SI 3)
1676 (udiv:SI (reg:SI 3) (reg:SI 4)))
1677 (set (reg:SI 4)
1678 (umod:SI (reg:SI 3) (reg:SI 4)))
1679 (clobber (match_scratch:SI 0 "=l"))
fada905b
MM
1680 (clobber (reg:SI 0))
1681 (clobber (match_scratch:CC 1 "=x"))
1682 (clobber (reg:CC 69))]
1683 "! TARGET_POWER && ! TARGET_POWERPC"
b7ff3d82
DE
1684 "bla __divus"
1685 [(set_attr "type" "idiv")])
fada905b
MM
1686
1687(define_insn "quoss_call"
1688 [(set (reg:SI 3)
1689 (div:SI (reg:SI 3) (reg:SI 4)))
cf27b467 1690 (clobber (match_scratch:SI 0 "=l"))]
8ffd9c51 1691 "! TARGET_POWER && ! TARGET_POWERPC"
b7ff3d82
DE
1692 "bla __quoss"
1693 [(set_attr "type" "idiv")])
0081a354 1694
fada905b
MM
1695(define_insn "quous_call"
1696 [(set (reg:SI 3)
1697 (udiv:SI (reg:SI 3) (reg:SI 4)))
1698 (clobber (match_scratch:SI 0 "=l"))
1699 (clobber (reg:SI 0))
1700 (clobber (match_scratch:CC 1 "=x"))
1701 (clobber (reg:CC 69))]
1702 "! TARGET_POWER && ! TARGET_POWERPC"
b7ff3d82
DE
1703 "bla __quous"
1704 [(set_attr "type" "idiv")])
8ffd9c51 1705\f
bb21487f 1706;; Logical instructions
1fd4e8c1 1707(define_insn "andsi3"
7cd5235b
MM
1708 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
1709 (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r")
1710 (match_operand:SI 2 "and_operand" "?r,L,K,J")))
1711 (clobber (match_scratch:CC 3 "=X,X,x,x"))]
1fd4e8c1
RK
1712 ""
1713 "@
1714 and %0,%1,%2
ca7f5001
RK
1715 {rlinm|rlwinm} %0,%1,0,%m2,%M2
1716 {andil.|andi.} %0,%1,%b2
7cd5235b
MM
1717 {andiu.|andis.} %0,%1,%u2"
1718 [(set_attr "length" "4,4,4,4")])
1fd4e8c1 1719
7cd5235b 1720(define_insn "*andsi3_internal2"
1fd4e8c1 1721 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x")
cd2b37d9 1722 (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r")
1fd4e8c1
RK
1723 (match_operand:SI 2 "and_operand" "r,K,J,L"))
1724 (const_int 0)))
1725 (clobber (match_scratch:SI 3 "=r,r,r,r"))]
1726 ""
1727 "@
1728 and. %3,%1,%2
ca7f5001
RK
1729 {andil.|andi.} %3,%1,%b2
1730 {andiu.|andis.} %3,%1,%u2
1731 {rlinm.|rlwinm.} %3,%1,0,%m2,%M2"
1fd4e8c1
RK
1732 [(set_attr "type" "compare,compare,compare,delayed_compare")])
1733
7cd5235b 1734(define_insn "*andsi3_internal3"
1fd4e8c1 1735 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x")
cd2b37d9 1736 (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r")
1fd4e8c1
RK
1737 (match_operand:SI 2 "and_operand" "r,K,J,L"))
1738 (const_int 0)))
cd2b37d9 1739 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
1fd4e8c1
RK
1740 (and:SI (match_dup 1) (match_dup 2)))]
1741 ""
1742 "@
1743 and. %0,%1,%2
ca7f5001
RK
1744 {andil.|andi.} %0,%1,%b2
1745 {andiu.|andis.} %0,%1,%u2
1746 {rlinm.|rlwinm.} %0,%1,0,%m2,%M2"
b19003d8 1747 [(set_attr "type" "compare,compare,compare,delayed_compare")])
1fd4e8c1 1748
7cd5235b 1749(define_expand "iorsi3"
cd2b37d9 1750 [(set (match_operand:SI 0 "gpc_reg_operand" "")
7cd5235b
MM
1751 (ior:SI (match_operand:SI 1 "gpc_reg_operand" "")
1752 (match_operand:SI 2 "reg_or_cint_operand" "")))]
1753 ""
f357808b
RK
1754 "
1755{
7cd5235b
MM
1756 if (GET_CODE (operands[2]) == CONST_INT
1757 && !logical_operand (operands[2], SImode))
1758 {
1759 HOST_WIDE_INT value = INTVAL (operands[2]);
1760 rtx tmp = ((reload_in_progress || reload_completed
1761 || rtx_equal_p (operands[0], operands[1]))
1762 ? operands[0] : gen_reg_rtx (SImode));
1763
a260abc9
DE
1764 emit_insn (gen_iorsi3 (tmp, operands[1],
1765 GEN_INT (value & (~ (HOST_WIDE_INT) 0xffff))));
1766 emit_insn (gen_iorsi3 (operands[0], tmp, GEN_INT (value & 0xffff)));
7cd5235b
MM
1767 DONE;
1768 }
f357808b
RK
1769}")
1770
7cd5235b
MM
1771(define_insn "*iorsi3_internal1"
1772 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
1773 (ior:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r")
1774 (match_operand:SI 2 "logical_operand" "r,K,J")))]
1fd4e8c1
RK
1775 ""
1776 "@
1777 or %0,%1,%2
ca7f5001 1778 {oril|ori} %0,%1,%b2
7cd5235b
MM
1779 {oriu|oris} %0,%1,%u2"
1780 [(set_attr "length" "4,4,4")])
1fd4e8c1 1781
7cd5235b 1782(define_insn "*iorsi3_internal2"
1fd4e8c1 1783 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
deb9225a 1784 (compare:CC (ior:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
cd2b37d9 1785 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1
RK
1786 (const_int 0)))
1787 (clobber (match_scratch:SI 3 "=r"))]
1788 ""
1789 "or. %3,%1,%2"
1790 [(set_attr "type" "compare")])
1791
7cd5235b 1792(define_insn "*iorsi3_internal3"
1fd4e8c1 1793 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
deb9225a 1794 (compare:CC (ior:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
cd2b37d9 1795 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 1796 (const_int 0)))
cd2b37d9 1797 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
1798 (ior:SI (match_dup 1) (match_dup 2)))]
1799 ""
1800 "or. %0,%1,%2"
1801 [(set_attr "type" "compare")])
1802
a260abc9
DE
1803;; Split an IOR that we can't do in one insn into two insns, each of which
1804;; does one 16-bit part. This is used by combine.
1805
1806(define_split
1807 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1808 (ior:SI (match_operand:SI 1 "gpc_reg_operand" "")
1809 (match_operand:SI 2 "non_logical_cint_operand" "")))]
1810 ""
1811 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))
1812 (set (match_dup 0) (ior:SI (match_dup 0) (match_dup 4)))]
1813"
1814{
1815 operands[3] = GEN_INT (INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff));
1816 operands[4] = GEN_INT (INTVAL (operands[2]) & 0xffff);
1817}")
1818
7cd5235b 1819(define_expand "xorsi3"
cd2b37d9 1820 [(set (match_operand:SI 0 "gpc_reg_operand" "")
7cd5235b
MM
1821 (xor:SI (match_operand:SI 1 "gpc_reg_operand" "")
1822 (match_operand:SI 2 "reg_or_cint_operand" "")))]
1fd4e8c1 1823 ""
7cd5235b 1824 "
1fd4e8c1 1825{
7cd5235b
MM
1826 if (GET_CODE (operands[2]) == CONST_INT
1827 && !logical_operand (operands[2], SImode))
1828 {
1829 HOST_WIDE_INT value = INTVAL (operands[2]);
1830 rtx tmp = ((reload_in_progress || reload_completed
1831 || rtx_equal_p (operands[0], operands[1]))
1832 ? operands[0] : gen_reg_rtx (SImode));
1833
a260abc9
DE
1834 emit_insn (gen_xorsi3 (tmp, operands[1],
1835 GEN_INT (value & (~ (HOST_WIDE_INT) 0xffff))));
1836 emit_insn (gen_xorsi3 (operands[0], tmp, GEN_INT (value & 0xffff)));
7cd5235b
MM
1837 DONE;
1838 }
1fd4e8c1
RK
1839}")
1840
7cd5235b
MM
1841(define_insn "*xorsi3_internal1"
1842 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
1843 (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r")
1844 (match_operand:SI 2 "logical_operand" "r,K,J")))]
1fd4e8c1
RK
1845 ""
1846 "@
1847 xor %0,%1,%2
ca7f5001 1848 {xoril|xori} %0,%1,%b2
7cd5235b
MM
1849 {xoriu|xoris} %0,%1,%u2"
1850 [(set_attr "length" "4,4,4")])
1fd4e8c1 1851
7cd5235b 1852(define_insn "*xorsi3_internal2"
1fd4e8c1 1853 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
deb9225a 1854 (compare:CC (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
cd2b37d9 1855 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1
RK
1856 (const_int 0)))
1857 (clobber (match_scratch:SI 3 "=r"))]
1858 ""
1859 "xor. %3,%1,%2"
1860 [(set_attr "type" "compare")])
1861
7cd5235b 1862(define_insn "*xorsi3_internal3"
1fd4e8c1 1863 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
deb9225a 1864 (compare:CC (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
cd2b37d9 1865 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 1866 (const_int 0)))
cd2b37d9 1867 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
1868 (xor:SI (match_dup 1) (match_dup 2)))]
1869 ""
1870 "xor. %0,%1,%2"
1871 [(set_attr "type" "compare")])
1872
a260abc9
DE
1873;; Split an XOR that we can't do in one insn into two insns, each of which
1874;; does one 16-bit part. This is used by combine.
1875
1876(define_split
1877 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1878 (xor:SI (match_operand:SI 1 "gpc_reg_operand" "")
1879 (match_operand:SI 2 "non_logical_cint_operand" "")))]
1880 ""
1881 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 3)))
1882 (set (match_dup 0) (xor:SI (match_dup 0) (match_dup 4)))]
1883"
1884{
1885 operands[3] = GEN_INT (INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff));
1886 operands[4] = GEN_INT (INTVAL (operands[2]) & 0xffff);
1887}")
1888
1889(define_insn "*eqvsi3_internal1"
cd2b37d9
RK
1890 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1891 (not:SI (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
1892 (match_operand:SI 2 "gpc_reg_operand" "r"))))]
1fd4e8c1
RK
1893 ""
1894 "eqv %0,%1,%2")
1895
a260abc9 1896(define_insn "*eqvsi3_internal2"
1fd4e8c1 1897 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
cd2b37d9
RK
1898 (compare:CC (not:SI (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
1899 (match_operand:SI 2 "gpc_reg_operand" "r")))
1fd4e8c1
RK
1900 (const_int 0)))
1901 (clobber (match_scratch:SI 3 "=r"))]
1902 ""
1903 "eqv. %3,%1,%2"
1904 [(set_attr "type" "compare")])
1905
a260abc9 1906(define_insn "*eqvsi3_internal3"
1fd4e8c1 1907 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
cd2b37d9
RK
1908 (compare:CC (not:SI (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
1909 (match_operand:SI 2 "gpc_reg_operand" "r")))
1fd4e8c1 1910 (const_int 0)))
cd2b37d9 1911 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
1912 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
1913 ""
1914 "eqv. %0,%1,%2"
1915 [(set_attr "type" "compare")])
1916
a260abc9 1917(define_insn "*andcsi3_internal1"
cd2b37d9
RK
1918 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1919 (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1920 (match_operand:SI 2 "gpc_reg_operand" "r")))]
1fd4e8c1
RK
1921 ""
1922 "andc %0,%2,%1")
1923
a260abc9 1924(define_insn "*andcsi3_internal2"
1fd4e8c1 1925 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
cd2b37d9
RK
1926 (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1927 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1
RK
1928 (const_int 0)))
1929 (clobber (match_scratch:SI 3 "=r"))]
1930 ""
1931 "andc. %3,%2,%1"
1932 [(set_attr "type" "compare")])
1933
a260abc9 1934(define_insn "*andcsi3_internal3"
1fd4e8c1 1935 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
cd2b37d9
RK
1936 (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1937 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 1938 (const_int 0)))
cd2b37d9 1939 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
1940 (and:SI (not:SI (match_dup 1)) (match_dup 2)))]
1941 ""
1942 "andc. %0,%2,%1"
1943 [(set_attr "type" "compare")])
1944
a260abc9 1945(define_insn "*iorcsi3_internal1"
cd2b37d9
RK
1946 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1947 (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1948 (match_operand:SI 2 "gpc_reg_operand" "r")))]
1fd4e8c1
RK
1949 ""
1950 "orc %0,%2,%1")
1951
a260abc9 1952(define_insn "*iorcsi3_internal2"
1fd4e8c1 1953 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
cd2b37d9
RK
1954 (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1955 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1
RK
1956 (const_int 0)))
1957 (clobber (match_scratch:SI 3 "=r"))]
1958 ""
1959 "orc. %3,%2,%1"
1960 [(set_attr "type" "compare")])
1961
a260abc9 1962(define_insn "*iorcsi3_internal3"
1fd4e8c1 1963 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
cd2b37d9
RK
1964 (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1965 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 1966 (const_int 0)))
cd2b37d9 1967 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
1968 (ior:SI (not:SI (match_dup 1)) (match_dup 2)))]
1969 ""
1970 "orc. %0,%2,%1"
1971 [(set_attr "type" "compare")])
1972
a260abc9 1973(define_insn "*nandsi3_internal1"
cd2b37d9 1974 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
deb9225a 1975 (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
cd2b37d9 1976 (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
1fd4e8c1
RK
1977 ""
1978 "nand %0,%1,%2")
1979
a260abc9 1980(define_insn "*nandsi3_internal2"
1fd4e8c1 1981 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
deb9225a 1982 (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
cd2b37d9 1983 (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")))
1fd4e8c1
RK
1984 (const_int 0)))
1985 (clobber (match_scratch:SI 3 "=r"))]
1986 ""
1987 "nand. %3,%1,%2"
1988 [(set_attr "type" "compare")])
1989
a260abc9 1990(define_insn "*nandsi3_internal3"
1fd4e8c1 1991 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
deb9225a 1992 (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
cd2b37d9 1993 (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")))
1fd4e8c1 1994 (const_int 0)))
cd2b37d9 1995 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
1996 (ior:SI (not:SI (match_dup 1)) (not:SI (match_dup 2))))]
1997 ""
1998 "nand. %0,%1,%2"
1999 [(set_attr "type" "compare")])
2000
a260abc9 2001(define_insn "*norsi3_internal1"
cd2b37d9 2002 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
deb9225a 2003 (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
cd2b37d9 2004 (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
1fd4e8c1
RK
2005 ""
2006 "nor %0,%1,%2")
2007
a260abc9 2008(define_insn "*norsi3_internal2"
1fd4e8c1 2009 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
deb9225a 2010 (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
cd2b37d9 2011 (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")))
1fd4e8c1
RK
2012 (const_int 0)))
2013 (clobber (match_scratch:SI 3 "=r"))]
2014 ""
2015 "nor. %3,%1,%2"
2016 [(set_attr "type" "compare")])
2017
a260abc9 2018(define_insn "*norsi3_internal3"
1fd4e8c1 2019 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
deb9225a 2020 (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
cd2b37d9 2021 (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")))
1fd4e8c1 2022 (const_int 0)))
cd2b37d9 2023 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2024 (and:SI (not:SI (match_dup 1)) (not:SI (match_dup 2))))]
2025 ""
2026 "nor. %0,%1,%2"
2027 [(set_attr "type" "compare")])
2028
2029;; maskir insn. We need four forms because things might be in arbitrary
2030;; orders. Don't define forms that only set CR fields because these
2031;; would modify an input register.
2032
7cd5235b 2033(define_insn "*maskir_internal1"
cd2b37d9 2034 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
01def764
RK
2035 (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))
2036 (match_operand:SI 1 "gpc_reg_operand" "0"))
2037 (and:SI (match_dup 2)
cd2b37d9 2038 (match_operand:SI 3 "gpc_reg_operand" "r"))))]
ca7f5001 2039 "TARGET_POWER"
01def764 2040 "maskir %0,%3,%2")
1fd4e8c1 2041
7cd5235b 2042(define_insn "*maskir_internal2"
242e8072 2043 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
01def764
RK
2044 (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))
2045 (match_operand:SI 1 "gpc_reg_operand" "0"))
cd2b37d9 2046 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r")
01def764 2047 (match_dup 2))))]
ca7f5001 2048 "TARGET_POWER"
01def764 2049 "maskir %0,%3,%2")
1fd4e8c1 2050
7cd5235b 2051(define_insn "*maskir_internal3"
cd2b37d9 2052 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
01def764 2053 (ior:SI (and:SI (match_operand:SI 2 "gpc_reg_operand" "r")
cd2b37d9 2054 (match_operand:SI 3 "gpc_reg_operand" "r"))
01def764
RK
2055 (and:SI (not:SI (match_dup 2))
2056 (match_operand:SI 1 "gpc_reg_operand" "0"))))]
ca7f5001 2057 "TARGET_POWER"
01def764 2058 "maskir %0,%3,%2")
1fd4e8c1 2059
7cd5235b 2060(define_insn "*maskir_internal4"
cd2b37d9
RK
2061 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2062 (ior:SI (and:SI (match_operand:SI 3 "gpc_reg_operand" "r")
01def764
RK
2063 (match_operand:SI 2 "gpc_reg_operand" "r"))
2064 (and:SI (not:SI (match_dup 2))
2065 (match_operand:SI 1 "gpc_reg_operand" "0"))))]
ca7f5001 2066 "TARGET_POWER"
01def764 2067 "maskir %0,%3,%2")
1fd4e8c1 2068
7cd5235b 2069(define_insn "*maskir_internal5"
1fd4e8c1
RK
2070 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
2071 (compare:CC
01def764
RK
2072 (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))
2073 (match_operand:SI 1 "gpc_reg_operand" "0"))
2074 (and:SI (match_dup 2)
cd2b37d9 2075 (match_operand:SI 3 "gpc_reg_operand" "r")))
1fd4e8c1 2076 (const_int 0)))
cd2b37d9 2077 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
01def764
RK
2078 (ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1))
2079 (and:SI (match_dup 2) (match_dup 3))))]
ca7f5001 2080 "TARGET_POWER"
01def764 2081 "maskir. %0,%3,%2"
1fd4e8c1
RK
2082 [(set_attr "type" "compare")])
2083
7cd5235b 2084(define_insn "*maskir_internal6"
1fd4e8c1
RK
2085 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
2086 (compare:CC
01def764
RK
2087 (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))
2088 (match_operand:SI 1 "gpc_reg_operand" "0"))
cd2b37d9 2089 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r")
01def764 2090 (match_dup 2)))
1fd4e8c1 2091 (const_int 0)))
242e8072 2092 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
01def764
RK
2093 (ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1))
2094 (and:SI (match_dup 3) (match_dup 2))))]
ca7f5001 2095 "TARGET_POWER"
01def764 2096 "maskir. %0,%3,%2"
1fd4e8c1
RK
2097 [(set_attr "type" "compare")])
2098
7cd5235b 2099(define_insn "*maskir_internal7"
1fd4e8c1
RK
2100 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
2101 (compare:CC
01def764 2102 (ior:SI (and:SI (match_operand:SI 2 "gpc_reg_operand" "r")
cd2b37d9 2103 (match_operand:SI 3 "gpc_reg_operand" "r"))
01def764
RK
2104 (and:SI (not:SI (match_dup 2))
2105 (match_operand:SI 1 "gpc_reg_operand" "0")))
1fd4e8c1 2106 (const_int 0)))
cd2b37d9 2107 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
01def764
RK
2108 (ior:SI (and:SI (match_dup 2) (match_dup 3))
2109 (and:SI (not:SI (match_dup 2)) (match_dup 1))))]
ca7f5001 2110 "TARGET_POWER"
01def764 2111 "maskir. %0,%3,%2"
1fd4e8c1
RK
2112 [(set_attr "type" "compare")])
2113
7cd5235b 2114(define_insn "*maskir_internal8"
1fd4e8c1
RK
2115 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
2116 (compare:CC
cd2b37d9 2117 (ior:SI (and:SI (match_operand:SI 3 "gpc_reg_operand" "r")
01def764
RK
2118 (match_operand:SI 2 "gpc_reg_operand" "r"))
2119 (and:SI (not:SI (match_dup 2))
2120 (match_operand:SI 1 "gpc_reg_operand" "0")))
1fd4e8c1 2121 (const_int 0)))
cd2b37d9 2122 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
01def764
RK
2123 (ior:SI (and:SI (match_dup 3) (match_dup 2))
2124 (and:SI (not:SI (match_dup 2)) (match_dup 1))))]
ca7f5001 2125 "TARGET_POWER"
01def764 2126 "maskir. %0,%3,%2"
1fd4e8c1
RK
2127 [(set_attr "type" "compare")])
2128\f
2129;; Rotate and shift insns, in all their variants. These support shifts,
2130;; field inserts and extracts, and various combinations thereof.
034c1be0
MM
2131(define_expand "insv"
2132 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
2133 (match_operand:SI 1 "const_int_operand" "i")
2134 (match_operand:SI 2 "const_int_operand" "i"))
2135 (match_operand:SI 3 "gpc_reg_operand" "r"))]
2136 ""
2137 "
2138{
2139 /* Do not handle 16/8 bit structures that fit in HI/QI modes directly, since
2140 the (SUBREG:SI (REG:HI xxx)) that is otherwise generated can confuse the
2141 compiler if the address of the structure is taken later. */
2142 if (GET_CODE (operands[0]) == SUBREG
2143 && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD))
2144 FAIL;
2145}")
2146
2147(define_insn ""
cd2b37d9 2148 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
1fd4e8c1
RK
2149 (match_operand:SI 1 "const_int_operand" "i")
2150 (match_operand:SI 2 "const_int_operand" "i"))
cd2b37d9 2151 (match_operand:SI 3 "gpc_reg_operand" "r"))]
1fd4e8c1
RK
2152 ""
2153 "*
2154{
2155 int start = INTVAL (operands[2]) & 31;
2156 int size = INTVAL (operands[1]) & 31;
2157
89e9f3a8
MM
2158 operands[4] = GEN_INT (32 - start - size);
2159 operands[1] = GEN_INT (start + size - 1);
a66078ee 2160 return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\";
1fd4e8c1
RK
2161}")
2162
d56d506a
RK
2163(define_insn ""
2164 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
2165 (match_operand:SI 1 "const_int_operand" "i")
2166 (match_operand:SI 2 "const_int_operand" "i"))
2167 (ashift:SI (match_operand:SI 3 "gpc_reg_operand" "r")
2168 (match_operand:SI 4 "const_int_operand" "i")))]
f0dc3f49 2169 "(32 - (INTVAL (operands[4]) & 31)) >= INTVAL (operands[1])"
d56d506a
RK
2170 "*
2171{
2172 int shift = INTVAL (operands[4]) & 31;
2173 int start = INTVAL (operands[2]) & 31;
2174 int size = INTVAL (operands[1]) & 31;
2175
89e9f3a8
MM
2176 operands[4] = GEN_INT (shift - start - size);
2177 operands[1] = GEN_INT (start + size - 1);
a66078ee 2178 return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\";
d56d506a
RK
2179}")
2180
2181(define_insn ""
2182 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
2183 (match_operand:SI 1 "const_int_operand" "i")
2184 (match_operand:SI 2 "const_int_operand" "i"))
2185 (ashiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r")
2186 (match_operand:SI 4 "const_int_operand" "i")))]
f0dc3f49 2187 "(32 - (INTVAL (operands[4]) & 31)) >= INTVAL (operands[1])"
d56d506a
RK
2188 "*
2189{
2190 int shift = INTVAL (operands[4]) & 31;
2191 int start = INTVAL (operands[2]) & 31;
2192 int size = INTVAL (operands[1]) & 31;
2193
89e9f3a8
MM
2194 operands[4] = GEN_INT (32 - shift - start - size);
2195 operands[1] = GEN_INT (start + size - 1);
a66078ee 2196 return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\";
d56d506a
RK
2197}")
2198
2199(define_insn ""
2200 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
2201 (match_operand:SI 1 "const_int_operand" "i")
2202 (match_operand:SI 2 "const_int_operand" "i"))
2203 (lshiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r")
2204 (match_operand:SI 4 "const_int_operand" "i")))]
95e8f2f3 2205 "(32 - (INTVAL (operands[4]) & 31)) >= INTVAL (operands[1])"
d56d506a
RK
2206 "*
2207{
2208 int shift = INTVAL (operands[4]) & 31;
2209 int start = INTVAL (operands[2]) & 31;
2210 int size = INTVAL (operands[1]) & 31;
2211
89e9f3a8
MM
2212 operands[4] = GEN_INT (32 - shift - start - size);
2213 operands[1] = GEN_INT (start + size - 1);
a66078ee 2214 return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\";
d56d506a
RK
2215}")
2216
2217(define_insn ""
2218 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
2219 (match_operand:SI 1 "const_int_operand" "i")
2220 (match_operand:SI 2 "const_int_operand" "i"))
2221 (zero_extract:SI (match_operand:SI 3 "gpc_reg_operand" "r")
2222 (match_operand:SI 4 "const_int_operand" "i")
2223 (match_operand:SI 5 "const_int_operand" "i")))]
2224 "INTVAL (operands[4]) >= INTVAL (operands[1])"
2225 "*
2226{
2227 int extract_start = INTVAL (operands[5]) & 31;
2228 int extract_size = INTVAL (operands[4]) & 31;
2229 int insert_start = INTVAL (operands[2]) & 31;
2230 int insert_size = INTVAL (operands[1]) & 31;
2231
2232/* Align extract field with insert field */
3a598fbe 2233 operands[5] = GEN_INT (extract_start + extract_size - insert_start - insert_size);
89e9f3a8 2234 operands[1] = GEN_INT (insert_start + insert_size - 1);
a66078ee 2235 return \"{rlimi|rlwimi} %0,%3,%h5,%h2,%h1\";
d56d506a
RK
2236}")
2237
685f3906
DE
2238(define_insn ""
2239 [(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r")
2240 (match_operand:DI 1 "const_int_operand" "i")
2241 (match_operand:DI 2 "const_int_operand" "i"))
2242 (match_operand:DI 3 "gpc_reg_operand" "r"))]
2243 "TARGET_POWERPC64"
2244 "*
2245{
2246 int start = INTVAL (operands[2]) & 63;
2247 int size = INTVAL (operands[1]) & 63;
2248
89e9f3a8 2249 operands[2] = GEN_INT (64 - start - size);
a66078ee 2250 return \"rldimi %0,%3,%H2,%H1\";
685f3906
DE
2251}")
2252
034c1be0
MM
2253(define_expand "extzv"
2254 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2255 (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2256 (match_operand:SI 2 "const_int_operand" "i")
2257 (match_operand:SI 3 "const_int_operand" "i")))]
2258 ""
2259 "
2260{
2261 /* Do not handle 16/8 bit structures that fit in HI/QI modes directly, since
2262 the (SUBREG:SI (REG:HI xxx)) that is otherwise generated can confuse the
2263 compiler if the address of the structure is taken later. */
2264 if (GET_CODE (operands[0]) == SUBREG
2265 && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD))
2266 FAIL;
2267}")
2268
2269(define_insn ""
cd2b37d9
RK
2270 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2271 (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2272 (match_operand:SI 2 "const_int_operand" "i")
2273 (match_operand:SI 3 "const_int_operand" "i")))]
2274 ""
2275 "*
2276{
2277 int start = INTVAL (operands[3]) & 31;
2278 int size = INTVAL (operands[2]) & 31;
2279
2280 if (start + size >= 32)
2281 operands[3] = const0_rtx;
2282 else
89e9f3a8 2283 operands[3] = GEN_INT (start + size);
ca7f5001 2284 return \"{rlinm|rlwinm} %0,%1,%3,%s2,31\";
1fd4e8c1
RK
2285}")
2286
2287(define_insn ""
2288 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
cd2b37d9 2289 (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2290 (match_operand:SI 2 "const_int_operand" "i")
2291 (match_operand:SI 3 "const_int_operand" "i"))
2292 (const_int 0)))
2293 (clobber (match_scratch:SI 4 "=r"))]
2294 ""
2295 "*
2296{
2297 int start = INTVAL (operands[3]) & 31;
2298 int size = INTVAL (operands[2]) & 31;
2299
a7a975e1
RK
2300 /* If the bitfield being tested fits in the upper or lower half of a
2301 word, it is possible to use andiu. or andil. to test it. This is
2302 useful because the condition register set-use delay is smaller for
2303 andi[ul]. than for rlinm. This doesn't work when the starting bit
2304 position is 0 because the LT and GT bits may be set wrong. */
2305
2306 if ((start > 0 && start + size <= 16) || start >= 16)
df031c43 2307 {
3a598fbe 2308 operands[3] = GEN_INT (((1 << (16 - (start & 15)))
df031c43
RK
2309 - (1 << (16 - (start & 15) - size))));
2310 if (start < 16)
ca7f5001 2311 return \"{andiu.|andis.} %4,%1,%3\";
df031c43 2312 else
ca7f5001 2313 return \"{andil.|andi.} %4,%1,%3\";
df031c43 2314 }
7e69e155 2315
1fd4e8c1
RK
2316 if (start + size >= 32)
2317 operands[3] = const0_rtx;
2318 else
89e9f3a8 2319 operands[3] = GEN_INT (start + size);
ca7f5001 2320 return \"{rlinm.|rlwinm.} %4,%1,%3,%s2,31\";
1fd4e8c1
RK
2321}"
2322 [(set_attr "type" "compare")])
2323
2324(define_insn ""
2325 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
cd2b37d9 2326 (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2327 (match_operand:SI 2 "const_int_operand" "i")
2328 (match_operand:SI 3 "const_int_operand" "i"))
2329 (const_int 0)))
cd2b37d9 2330 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2331 (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
2332 ""
2333 "*
2334{
2335 int start = INTVAL (operands[3]) & 31;
2336 int size = INTVAL (operands[2]) & 31;
2337
a7a975e1 2338 if (start >= 16 && start + size == 32)
df031c43 2339 {
89e9f3a8 2340 operands[3] = GEN_INT ((1 << (32 - start)) - 1);
ca7f5001 2341 return \"{andil.|andi.} %0,%1,%3\";
df031c43 2342 }
7e69e155 2343
1fd4e8c1
RK
2344 if (start + size >= 32)
2345 operands[3] = const0_rtx;
2346 else
89e9f3a8 2347 operands[3] = GEN_INT (start + size);
ca7f5001 2348 return \"{rlinm.|rlwinm.} %0,%1,%3,%s2,31\";
1fd4e8c1
RK
2349}"
2350 [(set_attr "type" "delayed_compare")])
2351
685f3906
DE
2352(define_insn ""
2353 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2354 (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2355 (match_operand:DI 2 "const_int_operand" "i")
2356 (match_operand:DI 3 "const_int_operand" "i")))]
2357 "TARGET_POWERPC64"
2358 "*
2359{
2360 int start = INTVAL (operands[3]) & 63;
2361 int size = INTVAL (operands[2]) & 63;
2362
2363 if (start + size >= 64)
2364 operands[3] = const0_rtx;
2365 else
89e9f3a8
MM
2366 operands[3] = GEN_INT (start + size);
2367 operands[2] = GEN_INT (64 - size);
685f3906
DE
2368 return \"rldicl %0,%1,%3,%2\";
2369}")
2370
2371(define_insn ""
2372 [(set (match_operand:CC 0 "gpc_reg_operand" "=x")
2373 (compare:CC (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2374 (match_operand:DI 2 "const_int_operand" "i")
2375 (match_operand:DI 3 "const_int_operand" "i"))
2376 (const_int 0)))
2377 (clobber (match_scratch:DI 4 "=r"))]
2378 "TARGET_POWERPC64"
2379 "*
2380{
2381 int start = INTVAL (operands[3]) & 63;
2382 int size = INTVAL (operands[2]) & 63;
2383
2384 if (start + size >= 64)
2385 operands[3] = const0_rtx;
2386 else
89e9f3a8
MM
2387 operands[3] = GEN_INT (start + size);
2388 operands[2] = GEN_INT (64 - size);
685f3906
DE
2389 return \"rldicl. %4,%1,%3,%2\";
2390}")
2391
2392(define_insn ""
2393 [(set (match_operand:CC 4 "gpc_reg_operand" "=x")
2394 (compare:CC (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2395 (match_operand:DI 2 "const_int_operand" "i")
2396 (match_operand:DI 3 "const_int_operand" "i"))
2397 (const_int 0)))
2398 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
2399 (zero_extract:DI (match_dup 1) (match_dup 2) (match_dup 3)))]
2400 "TARGET_POWERPC64"
2401 "*
2402{
2403 int start = INTVAL (operands[3]) & 63;
2404 int size = INTVAL (operands[2]) & 63;
2405
2406 if (start + size >= 64)
2407 operands[3] = const0_rtx;
2408 else
89e9f3a8
MM
2409 operands[3] = GEN_INT (start + size);
2410 operands[2] = GEN_INT (64 - size);
685f3906
DE
2411 return \"rldicl. %0,%1,%3,%2\";
2412}")
2413
1fd4e8c1 2414(define_insn "rotlsi3"
cd2b37d9
RK
2415 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2416 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2417 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
2418 ""
ca7f5001 2419 "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xffffffff")
1fd4e8c1 2420
a260abc9 2421(define_insn "*rotlsi3_internal2"
1fd4e8c1 2422 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
cd2b37d9 2423 (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2424 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2425 (const_int 0)))
2426 (clobber (match_scratch:SI 3 "=r"))]
2427 ""
ca7f5001 2428 "{rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffffffff"
1fd4e8c1
RK
2429 [(set_attr "type" "delayed_compare")])
2430
a260abc9 2431(define_insn "*rotlsi3_internal3"
1fd4e8c1 2432 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
cd2b37d9 2433 (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2434 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2435 (const_int 0)))
cd2b37d9 2436 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2437 (rotate:SI (match_dup 1) (match_dup 2)))]
2438 ""
ca7f5001 2439 "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffffffff"
1fd4e8c1
RK
2440 [(set_attr "type" "delayed_compare")])
2441
a260abc9 2442(define_insn "*rotlsi3_internal4"
cd2b37d9
RK
2443 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2444 (and:SI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2445 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2446 (match_operand:SI 3 "mask_operand" "L")))]
2447 ""
ca7f5001 2448 "{rl%I2nm|rlw%I2nm} %0,%1,%h2,%m3,%M3")
1fd4e8c1 2449
a260abc9 2450(define_insn "*rotlsi3_internal5"
1fd4e8c1
RK
2451 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2452 (compare:CC (and:SI
cd2b37d9 2453 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2454 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2455 (match_operand:SI 3 "mask_operand" "L"))
2456 (const_int 0)))
2457 (clobber (match_scratch:SI 4 "=r"))]
2458 ""
ca7f5001 2459 "{rl%I2nm.|rlw%I2nm.} %4,%1,%h2,%m3,%M3"
1fd4e8c1
RK
2460 [(set_attr "type" "delayed_compare")])
2461
a260abc9 2462(define_insn "*rotlsi3_internal6"
1fd4e8c1
RK
2463 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
2464 (compare:CC (and:SI
cd2b37d9 2465 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2466 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2467 (match_operand:SI 3 "mask_operand" "L"))
2468 (const_int 0)))
cd2b37d9 2469 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2470 (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2471 ""
ca7f5001 2472 "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,%m3,%M3"
1fd4e8c1
RK
2473 [(set_attr "type" "delayed_compare")])
2474
a260abc9 2475(define_insn "*rotlsi3_internal7"
cd2b37d9 2476 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2477 (zero_extend:SI
2478 (subreg:QI
cd2b37d9 2479 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2480 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0)))]
2481 ""
ca7f5001 2482 "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xff")
1fd4e8c1 2483
a260abc9 2484(define_insn "*rotlsi3_internal8"
1fd4e8c1
RK
2485 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2486 (compare:CC (zero_extend:SI
2487 (subreg:QI
cd2b37d9 2488 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2489 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0))
2490 (const_int 0)))
2491 (clobber (match_scratch:SI 3 "=r"))]
2492 ""
ca7f5001 2493 "{rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xff"
1fd4e8c1
RK
2494 [(set_attr "type" "delayed_compare")])
2495
a260abc9 2496(define_insn "*rotlsi3_internal9"
1fd4e8c1
RK
2497 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2498 (compare:CC (zero_extend:SI
2499 (subreg:QI
cd2b37d9 2500 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2501 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0))
2502 (const_int 0)))
cd2b37d9 2503 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2504 (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
2505 ""
ca7f5001 2506 "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xff"
1fd4e8c1
RK
2507 [(set_attr "type" "delayed_compare")])
2508
a260abc9 2509(define_insn "*rotlsi3_internal10"
cd2b37d9 2510 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2511 (zero_extend:SI
2512 (subreg:HI
cd2b37d9 2513 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2514 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0)))]
2515 ""
ca7f5001 2516 "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xffff")
1fd4e8c1 2517
a260abc9 2518(define_insn "*rotlsi3_internal11"
1fd4e8c1
RK
2519 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2520 (compare:CC (zero_extend:SI
2521 (subreg:HI
cd2b37d9 2522 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2523 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0))
2524 (const_int 0)))
2525 (clobber (match_scratch:SI 3 "=r"))]
2526 ""
ca7f5001 2527 "{rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffff"
1fd4e8c1
RK
2528 [(set_attr "type" "delayed_compare")])
2529
a260abc9 2530(define_insn "*rotlsi3_internal12"
1fd4e8c1
RK
2531 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2532 (compare:CC (zero_extend:SI
2533 (subreg:HI
cd2b37d9 2534 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2535 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0))
2536 (const_int 0)))
cd2b37d9 2537 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2538 (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
2539 ""
ca7f5001 2540 "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffff"
1fd4e8c1
RK
2541 [(set_attr "type" "delayed_compare")])
2542
2543;; Note that we use "sle." instead of "sl." so that we can set
2544;; SHIFT_COUNT_TRUNCATED.
2545
ca7f5001
RK
2546(define_expand "ashlsi3"
2547 [(use (match_operand:SI 0 "gpc_reg_operand" ""))
2548 (use (match_operand:SI 1 "gpc_reg_operand" ""))
2549 (use (match_operand:SI 2 "reg_or_cint_operand" ""))]
2550 ""
2551 "
2552{
2553 if (TARGET_POWER)
2554 emit_insn (gen_ashlsi3_power (operands[0], operands[1], operands[2]));
2555 else
25c341fa 2556 emit_insn (gen_ashlsi3_no_power (operands[0], operands[1], operands[2]));
ca7f5001
RK
2557 DONE;
2558}")
2559
2560(define_insn "ashlsi3_power"
cd2b37d9
RK
2561 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
2562 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
2563 (match_operand:SI 2 "reg_or_cint_operand" "r,i")))
2564 (clobber (match_scratch:SI 3 "=q,X"))]
ca7f5001 2565 "TARGET_POWER"
1fd4e8c1
RK
2566 "@
2567 sle %0,%1,%2
ca7f5001
RK
2568 {sli|slwi} %0,%1,%h2"
2569 [(set_attr "length" "8")])
2570
25c341fa 2571(define_insn "ashlsi3_no_power"
ca7f5001
RK
2572 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2573 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2574 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
25c341fa 2575 "! TARGET_POWER"
d904e9ed 2576 "{sl|slw}%I2 %0,%1,%h2"
b19003d8 2577 [(set_attr "length" "8")])
1fd4e8c1
RK
2578
2579(define_insn ""
2580 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
cd2b37d9 2581 (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
2582 (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
2583 (const_int 0)))
2584 (clobber (match_scratch:SI 3 "=r,r"))
2585 (clobber (match_scratch:SI 4 "=q,X"))]
ca7f5001 2586 "TARGET_POWER"
1fd4e8c1
RK
2587 "@
2588 sle. %3,%1,%2
ca7f5001
RK
2589 {sli.|slwi.} %3,%1,%h2"
2590 [(set_attr "type" "delayed_compare")])
25c341fa 2591
ca7f5001
RK
2592(define_insn ""
2593 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2594 (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2595 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2596 (const_int 0)))
2597 (clobber (match_scratch:SI 3 "=r"))]
8ffd9c51 2598 "! TARGET_POWER"
d904e9ed 2599 "{sl|slw}%I2. %3,%1,%h2"
1fd4e8c1
RK
2600 [(set_attr "type" "delayed_compare")])
2601
2602(define_insn ""
2603 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
cd2b37d9 2604 (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
2605 (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
2606 (const_int 0)))
cd2b37d9 2607 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
2608 (ashift:SI (match_dup 1) (match_dup 2)))
2609 (clobber (match_scratch:SI 4 "=q,X"))]
ca7f5001 2610 "TARGET_POWER"
1fd4e8c1
RK
2611 "@
2612 sle. %0,%1,%2
ca7f5001
RK
2613 {sli.|slwi.} %0,%1,%h2"
2614 [(set_attr "type" "delayed_compare")])
25c341fa 2615
ca7f5001
RK
2616(define_insn ""
2617 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2618 (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2619 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2620 (const_int 0)))
2621 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
2622 (ashift:SI (match_dup 1) (match_dup 2)))]
8ffd9c51 2623 "! TARGET_POWER"
d904e9ed 2624 "{sl|slw}%I2. %0,%1,%h2"
1fd4e8c1
RK
2625 [(set_attr "type" "delayed_compare")])
2626
2627(define_insn ""
cd2b37d9
RK
2628 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2629 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2630 (match_operand:SI 2 "const_int_operand" "i"))
2631 (match_operand:SI 3 "mask_operand" "L")))]
2632 "includes_lshift_p (operands[2], operands[3])"
d56d506a 2633 "{rlinm|rlwinm} %0,%1,%h2,%m3,%M3")
1fd4e8c1
RK
2634
2635(define_insn ""
2636 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2637 (compare:CC
cd2b37d9 2638 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2639 (match_operand:SI 2 "const_int_operand" "i"))
2640 (match_operand:SI 3 "mask_operand" "L"))
2641 (const_int 0)))
2642 (clobber (match_scratch:SI 4 "=r"))]
2643 "includes_lshift_p (operands[2], operands[3])"
d56d506a 2644 "{rlinm.|rlwinm.} %4,%1,%h2,%m3,%M3"
1fd4e8c1
RK
2645 [(set_attr "type" "delayed_compare")])
2646
2647(define_insn ""
2648 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
2649 (compare:CC
cd2b37d9 2650 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2651 (match_operand:SI 2 "const_int_operand" "i"))
2652 (match_operand:SI 3 "mask_operand" "L"))
2653 (const_int 0)))
cd2b37d9 2654 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2655 (and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2656 "includes_lshift_p (operands[2], operands[3])"
d56d506a 2657 "{rlinm.|rlwinm.} %0,%1,%h2,%m3,%M3"
1fd4e8c1
RK
2658 [(set_attr "type" "delayed_compare")])
2659
ca7f5001 2660;; The AIX assembler mis-handles "sri x,x,0", so write that case as
5c23c401 2661;; "sli x,x,0".
ca7f5001
RK
2662(define_expand "lshrsi3"
2663 [(use (match_operand:SI 0 "gpc_reg_operand" ""))
2664 (use (match_operand:SI 1 "gpc_reg_operand" ""))
2665 (use (match_operand:SI 2 "reg_or_cint_operand" ""))]
2666 ""
2667 "
2668{
2669 if (TARGET_POWER)
2670 emit_insn (gen_lshrsi3_power (operands[0], operands[1], operands[2]));
2671 else
25c341fa 2672 emit_insn (gen_lshrsi3_no_power (operands[0], operands[1], operands[2]));
ca7f5001
RK
2673 DONE;
2674}")
2675
2676(define_insn "lshrsi3_power"
bdf423cb
MM
2677 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
2678 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r")
2679 (match_operand:SI 2 "reg_or_cint_operand" "r,O,i")))
2680 (clobber (match_scratch:SI 3 "=q,X,X"))]
ca7f5001 2681 "TARGET_POWER"
1fd4e8c1
RK
2682 "@
2683 sre %0,%1,%2
bdf423cb 2684 mr %0,%1
ca7f5001
RK
2685 {s%A2i|s%A2wi} %0,%1,%h2")
2686
25c341fa 2687(define_insn "lshrsi3_no_power"
bdf423cb
MM
2688 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
2689 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
2690 (match_operand:SI 2 "reg_or_cint_operand" "O,ri")))]
25c341fa 2691 "! TARGET_POWER"
bdf423cb
MM
2692 "@
2693 mr %0,%1
2694 {sr|srw}%I2 %0,%1,%h2")
1fd4e8c1
RK
2695
2696(define_insn ""
bdf423cb
MM
2697 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x")
2698 (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r")
2699 (match_operand:SI 2 "reg_or_cint_operand" "r,O,i"))
1fd4e8c1 2700 (const_int 0)))
bdf423cb
MM
2701 (clobber (match_scratch:SI 3 "=r,X,r"))
2702 (clobber (match_scratch:SI 4 "=q,X,X"))]
ca7f5001 2703 "TARGET_POWER"
1fd4e8c1
RK
2704 "@
2705 sre. %3,%1,%2
bdf423cb 2706 mr. %1,%1
ca7f5001
RK
2707 {s%A2i.|s%A2wi.} %3,%1,%h2"
2708 [(set_attr "type" "delayed_compare")])
2709
2710(define_insn ""
bdf423cb
MM
2711 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
2712 (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
2713 (match_operand:SI 2 "reg_or_cint_operand" "O,ri"))
ca7f5001 2714 (const_int 0)))
bdf423cb 2715 (clobber (match_scratch:SI 3 "=X,r"))]
25c341fa 2716 "! TARGET_POWER"
bdf423cb
MM
2717 "@
2718 mr. %1,%1
2719 {sr|srw}%I2. %3,%1,%h2"
1fd4e8c1
RK
2720 [(set_attr "type" "delayed_compare")])
2721
2722(define_insn ""
bdf423cb
MM
2723 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x")
2724 (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r")
2725 (match_operand:SI 2 "reg_or_cint_operand" "r,O,i"))
1fd4e8c1 2726 (const_int 0)))
bdf423cb 2727 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
1fd4e8c1 2728 (lshiftrt:SI (match_dup 1) (match_dup 2)))
bdf423cb 2729 (clobber (match_scratch:SI 4 "=q,X,X"))]
ca7f5001 2730 "TARGET_POWER"
1fd4e8c1
RK
2731 "@
2732 sre. %0,%1,%2
bdf423cb 2733 mr. %0,%1
ca7f5001
RK
2734 {s%A2i.|s%A2wi.} %0,%1,%h2"
2735 [(set_attr "type" "delayed_compare")])
2736
2737(define_insn ""
bdf423cb
MM
2738 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
2739 (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
2740 (match_operand:SI 2 "reg_or_cint_operand" "O,ri"))
ca7f5001 2741 (const_int 0)))
bdf423cb 2742 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
ca7f5001 2743 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
25c341fa 2744 "! TARGET_POWER"
bdf423cb
MM
2745 "@
2746 mr. %0,%1
2747 {sr|srw}%I2. %0,%1,%h2"
1fd4e8c1
RK
2748 [(set_attr "type" "delayed_compare")])
2749
2750(define_insn ""
cd2b37d9
RK
2751 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2752 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2753 (match_operand:SI 2 "const_int_operand" "i"))
2754 (match_operand:SI 3 "mask_operand" "L")))]
2755 "includes_rshift_p (operands[2], operands[3])"
ca7f5001 2756 "{rlinm|rlwinm} %0,%1,%s2,%m3,%M3")
1fd4e8c1
RK
2757
2758(define_insn ""
2759 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2760 (compare:CC
cd2b37d9 2761 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2762 (match_operand:SI 2 "const_int_operand" "i"))
2763 (match_operand:SI 3 "mask_operand" "L"))
2764 (const_int 0)))
2765 (clobber (match_scratch:SI 4 "=r"))]
2766 "includes_rshift_p (operands[2], operands[3])"
ca7f5001 2767 "{rlinm.|rlwinm.} %4,%1,%s2,%m3,%M3"
1fd4e8c1
RK
2768 [(set_attr "type" "delayed_compare")])
2769
2770(define_insn ""
2771 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
2772 (compare:CC
cd2b37d9 2773 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2774 (match_operand:SI 2 "const_int_operand" "i"))
2775 (match_operand:SI 3 "mask_operand" "L"))
2776 (const_int 0)))
cd2b37d9 2777 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2778 (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2779 "includes_rshift_p (operands[2], operands[3])"
ca7f5001 2780 "{rlinm.|rlwinm.} %0,%1,%s2,%m3,%M3"
1fd4e8c1
RK
2781 [(set_attr "type" "delayed_compare")])
2782
2783(define_insn ""
cd2b37d9 2784 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2785 (zero_extend:SI
2786 (subreg:QI
cd2b37d9 2787 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 2788 (match_operand:SI 2 "const_int_operand" "i")) 0)))]
89e9f3a8 2789 "includes_rshift_p (operands[2], GEN_INT (255))"
ca7f5001 2790 "{rlinm|rlwinm} %0,%1,%s2,0xff")
1fd4e8c1
RK
2791
2792(define_insn ""
2793 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2794 (compare:CC
2795 (zero_extend:SI
2796 (subreg:QI
cd2b37d9 2797 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2798 (match_operand:SI 2 "const_int_operand" "i")) 0))
2799 (const_int 0)))
2800 (clobber (match_scratch:SI 3 "=r"))]
89e9f3a8 2801 "includes_rshift_p (operands[2], GEN_INT (255))"
ca7f5001 2802 "{rlinm.|rlwinm.} %3,%1,%s2,0xff"
1fd4e8c1
RK
2803 [(set_attr "type" "delayed_compare")])
2804
2805(define_insn ""
2806 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2807 (compare:CC
2808 (zero_extend:SI
2809 (subreg:QI
cd2b37d9 2810 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2811 (match_operand:SI 2 "const_int_operand" "i")) 0))
2812 (const_int 0)))
cd2b37d9 2813 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1 2814 (zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
89e9f3a8 2815 "includes_rshift_p (operands[2], GEN_INT (255))"
ca7f5001 2816 "{rlinm.|rlwinm.} %0,%1,%s2,0xff"
1fd4e8c1
RK
2817 [(set_attr "type" "delayed_compare")])
2818
2819(define_insn ""
cd2b37d9 2820 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2821 (zero_extend:SI
2822 (subreg:HI
cd2b37d9 2823 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 2824 (match_operand:SI 2 "const_int_operand" "i")) 0)))]
89e9f3a8 2825 "includes_rshift_p (operands[2], GEN_INT (65535))"
ca7f5001 2826 "{rlinm|rlwinm} %0,%1,%s2,0xffff")
1fd4e8c1
RK
2827
2828(define_insn ""
2829 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2830 (compare:CC
2831 (zero_extend:SI
2832 (subreg:HI
cd2b37d9 2833 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2834 (match_operand:SI 2 "const_int_operand" "i")) 0))
2835 (const_int 0)))
2836 (clobber (match_scratch:SI 3 "=r"))]
89e9f3a8 2837 "includes_rshift_p (operands[2], GEN_INT (65535))"
ca7f5001 2838 "{rlinm.|rlwinm.} %3,%1,%s2,0xffff"
1fd4e8c1
RK
2839 [(set_attr "type" "delayed_compare")])
2840
2841(define_insn ""
2842 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2843 (compare:CC
2844 (zero_extend:SI
2845 (subreg:HI
cd2b37d9 2846 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2847 (match_operand:SI 2 "const_int_operand" "i")) 0))
2848 (const_int 0)))
cd2b37d9 2849 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1 2850 (zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
89e9f3a8 2851 "includes_rshift_p (operands[2], GEN_INT (65535))"
ca7f5001 2852 "{rlinm.|rlwinm.} %0,%1,%s2,0xffff"
1fd4e8c1
RK
2853 [(set_attr "type" "delayed_compare")])
2854
2855(define_insn ""
cd2b37d9 2856 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
1fd4e8c1 2857 (const_int 1)
cd2b37d9
RK
2858 (match_operand:SI 1 "gpc_reg_operand" "r"))
2859 (ashiftrt:SI (match_operand:SI 2 "gpc_reg_operand" "r")
1fd4e8c1 2860 (const_int 31)))]
ca7f5001 2861 "TARGET_POWER"
1fd4e8c1
RK
2862 "rrib %0,%1,%2")
2863
2864(define_insn ""
cd2b37d9 2865 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
1fd4e8c1 2866 (const_int 1)
cd2b37d9
RK
2867 (match_operand:SI 1 "gpc_reg_operand" "r"))
2868 (lshiftrt:SI (match_operand:SI 2 "gpc_reg_operand" "r")
1fd4e8c1 2869 (const_int 31)))]
ca7f5001 2870 "TARGET_POWER"
1fd4e8c1
RK
2871 "rrib %0,%1,%2")
2872
2873(define_insn ""
cd2b37d9 2874 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
1fd4e8c1 2875 (const_int 1)
cd2b37d9
RK
2876 (match_operand:SI 1 "gpc_reg_operand" "r"))
2877 (zero_extract:SI (match_operand:SI 2 "gpc_reg_operand" "r")
1fd4e8c1
RK
2878 (const_int 1)
2879 (const_int 0)))]
ca7f5001 2880 "TARGET_POWER"
1fd4e8c1
RK
2881 "rrib %0,%1,%2")
2882
ca7f5001
RK
2883(define_expand "ashrsi3"
2884 [(set (match_operand:SI 0 "gpc_reg_operand" "")
2885 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
2886 (match_operand:SI 2 "reg_or_cint_operand" "")))]
2887 ""
2888 "
2889{
2890 if (TARGET_POWER)
2891 emit_insn (gen_ashrsi3_power (operands[0], operands[1], operands[2]));
2892 else
25c341fa 2893 emit_insn (gen_ashrsi3_no_power (operands[0], operands[1], operands[2]));
ca7f5001
RK
2894 DONE;
2895}")
2896
2897(define_insn "ashrsi3_power"
cd2b37d9
RK
2898 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
2899 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
2900 (match_operand:SI 2 "reg_or_cint_operand" "r,i")))
2901 (clobber (match_scratch:SI 3 "=q,X"))]
ca7f5001 2902 "TARGET_POWER"
1fd4e8c1
RK
2903 "@
2904 srea %0,%1,%2
ca7f5001
RK
2905 {srai|srawi} %0,%1,%h2")
2906
25c341fa 2907(define_insn "ashrsi3_no_power"
ca7f5001
RK
2908 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2909 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2910 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
25c341fa 2911 "! TARGET_POWER"
d904e9ed 2912 "{sra|sraw}%I2 %0,%1,%h2")
1fd4e8c1
RK
2913
2914(define_insn ""
2915 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
cd2b37d9 2916 (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
2917 (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
2918 (const_int 0)))
2919 (clobber (match_scratch:SI 3 "=r,r"))
2920 (clobber (match_scratch:SI 4 "=q,X"))]
ca7f5001 2921 "TARGET_POWER"
1fd4e8c1
RK
2922 "@
2923 srea. %3,%1,%2
ca7f5001
RK
2924 {srai.|srawi.} %3,%1,%h2"
2925 [(set_attr "type" "delayed_compare")])
2926
2927(define_insn ""
2928 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2929 (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2930 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2931 (const_int 0)))
2932 (clobber (match_scratch:SI 3 "=r"))]
25c341fa 2933 "! TARGET_POWER"
d904e9ed 2934 "{sra|sraw}%I2. %3,%1,%h2"
1fd4e8c1
RK
2935 [(set_attr "type" "delayed_compare")])
2936
2937(define_insn ""
2938 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
cd2b37d9 2939 (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
2940 (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
2941 (const_int 0)))
cd2b37d9 2942 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
2943 (ashiftrt:SI (match_dup 1) (match_dup 2)))
2944 (clobber (match_scratch:SI 4 "=q,X"))]
ca7f5001 2945 "TARGET_POWER"
1fd4e8c1
RK
2946 "@
2947 srea. %0,%1,%2
7f340546 2948 {srai.|srawi.} %0,%1,%h2"
1fd4e8c1
RK
2949 [(set_attr "type" "delayed_compare")])
2950
ca7f5001
RK
2951(define_insn ""
2952 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2953 (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2954 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2955 (const_int 0)))
2956 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
2957 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
25c341fa 2958 "! TARGET_POWER"
d904e9ed 2959 "{sra|sraw}%I2. %0,%1,%h2"
ca7f5001 2960 [(set_attr "type" "delayed_compare")])
1fd4e8c1
RK
2961\f
2962;; Floating-point insns, excluding normal data motion.
2963;;
ca7f5001
RK
2964;; PowerPC has a full set of single-precision floating point instructions.
2965;;
2966;; For the POWER architecture, we pretend that we have both SFmode and
2967;; DFmode insns, while, in fact, all fp insns are actually done in double.
2968;; The only conversions we will do will be when storing to memory. In that
2969;; case, we will use the "frsp" instruction before storing.
1fd4e8c1
RK
2970;;
2971;; Note that when we store into a single-precision memory location, we need to
2972;; use the frsp insn first. If the register being stored isn't dead, we
2973;; need a scratch register for the frsp. But this is difficult when the store
2974;; is done by reload. It is not incorrect to do the frsp on the register in
2975;; this case, we just lose precision that we would have otherwise gotten but
2976;; is not guaranteed. Perhaps this should be tightened up at some point.
2977
e8112008 2978(define_insn "extendsfdf2"
cd2b37d9 2979 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
e8112008 2980 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f")))]
d14a6d05 2981 "TARGET_HARD_FLOAT"
e8112008 2982 "*
5c30aff8 2983{
e8112008
RK
2984 if (REGNO (operands[0]) == REGNO (operands[1]))
2985 return \"\";
2986 else
2987 return \"fmr %0,%1\";
2988}"
2989 [(set_attr "type" "fp")])
1fd4e8c1
RK
2990
2991(define_insn "truncdfsf2"
cd2b37d9
RK
2992 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2993 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "f")))]
d14a6d05 2994 "TARGET_HARD_FLOAT"
dcac138d 2995 "frsp %0,%1"
1fd4e8c1
RK
2996 [(set_attr "type" "fp")])
2997
455350f4
RK
2998(define_insn "aux_truncdfsf2"
2999 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3000 (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] 0))]
3001 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
3002 "frsp %0,%1"
3003 [(set_attr "type" "fp")])
3004
1fd4e8c1 3005(define_insn "negsf2"
cd2b37d9
RK
3006 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3007 (neg:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
d14a6d05 3008 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
3009 "fneg %0,%1"
3010 [(set_attr "type" "fp")])
3011
3012(define_insn "abssf2"
cd2b37d9
RK
3013 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3014 (abs:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
d14a6d05 3015 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
3016 "fabs %0,%1"
3017 [(set_attr "type" "fp")])
3018
3019(define_insn ""
cd2b37d9
RK
3020 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3021 (neg:SF (abs:SF (match_operand:SF 1 "gpc_reg_operand" "f"))))]
d14a6d05 3022 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
3023 "fnabs %0,%1"
3024 [(set_attr "type" "fp")])
3025
ca7f5001
RK
3026(define_expand "addsf3"
3027 [(set (match_operand:SF 0 "gpc_reg_operand" "")
3028 (plus:SF (match_operand:SF 1 "gpc_reg_operand" "")
3029 (match_operand:SF 2 "gpc_reg_operand" "")))]
d14a6d05 3030 "TARGET_HARD_FLOAT"
ca7f5001
RK
3031 "")
3032
3033(define_insn ""
cd2b37d9
RK
3034 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3035 (plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3036 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 3037 "TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 3038 "fadds %0,%1,%2"
ca7f5001
RK
3039 [(set_attr "type" "fp")])
3040
3041(define_insn ""
3042 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3043 (plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3044 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 3045 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 3046 "{fa|fadd} %0,%1,%2"
ca7f5001
RK
3047 [(set_attr "type" "fp")])
3048
3049(define_expand "subsf3"
3050 [(set (match_operand:SF 0 "gpc_reg_operand" "")
3051 (minus:SF (match_operand:SF 1 "gpc_reg_operand" "")
3052 (match_operand:SF 2 "gpc_reg_operand" "")))]
d14a6d05 3053 "TARGET_HARD_FLOAT"
ca7f5001
RK
3054 "")
3055
3056(define_insn ""
3057 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3058 (minus:SF (match_operand:SF 1 "gpc_reg_operand" "f")
3059 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 3060 "TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 3061 "fsubs %0,%1,%2"
1fd4e8c1
RK
3062 [(set_attr "type" "fp")])
3063
ca7f5001 3064(define_insn ""
cd2b37d9
RK
3065 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3066 (minus:SF (match_operand:SF 1 "gpc_reg_operand" "f")
3067 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 3068 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 3069 "{fs|fsub} %0,%1,%2"
ca7f5001
RK
3070 [(set_attr "type" "fp")])
3071
3072(define_expand "mulsf3"
3073 [(set (match_operand:SF 0 "gpc_reg_operand" "")
3074 (mult:SF (match_operand:SF 1 "gpc_reg_operand" "")
3075 (match_operand:SF 2 "gpc_reg_operand" "")))]
d14a6d05 3076 "TARGET_HARD_FLOAT"
ca7f5001
RK
3077 "")
3078
3079(define_insn ""
3080 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3081 (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3082 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 3083 "TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 3084 "fmuls %0,%1,%2"
1fd4e8c1
RK
3085 [(set_attr "type" "fp")])
3086
ca7f5001 3087(define_insn ""
cd2b37d9
RK
3088 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3089 (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3090 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 3091 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 3092 "{fm|fmul} %0,%1,%2"
0780f386 3093 [(set_attr "type" "dmul")])
1fd4e8c1 3094
ca7f5001
RK
3095(define_expand "divsf3"
3096 [(set (match_operand:SF 0 "gpc_reg_operand" "")
3097 (div:SF (match_operand:SF 1 "gpc_reg_operand" "")
3098 (match_operand:SF 2 "gpc_reg_operand" "")))]
d14a6d05 3099 "TARGET_HARD_FLOAT"
ca7f5001
RK
3100 "")
3101
3102(define_insn ""
cd2b37d9
RK
3103 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3104 (div:SF (match_operand:SF 1 "gpc_reg_operand" "f")
3105 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 3106 "TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 3107 "fdivs %0,%1,%2"
ca7f5001
RK
3108 [(set_attr "type" "sdiv")])
3109
3110(define_insn ""
3111 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3112 (div:SF (match_operand:SF 1 "gpc_reg_operand" "f")
3113 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 3114 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 3115 "{fd|fdiv} %0,%1,%2"
0780f386 3116 [(set_attr "type" "ddiv")])
1fd4e8c1
RK
3117
3118(define_insn ""
cd2b37d9
RK
3119 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3120 (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3121 (match_operand:SF 2 "gpc_reg_operand" "f"))
3122 (match_operand:SF 3 "gpc_reg_operand" "f")))]
38c1f2d7 3123 "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
b26c8351 3124 "fmadds %0,%1,%2,%3"
ca7f5001
RK
3125 [(set_attr "type" "fp")])
3126
3127(define_insn ""
3128 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3129 (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3130 (match_operand:SF 2 "gpc_reg_operand" "f"))
3131 (match_operand:SF 3 "gpc_reg_operand" "f")))]
38c1f2d7 3132 "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
b26c8351 3133 "{fma|fmadd} %0,%1,%2,%3"
cf27b467 3134 [(set_attr "type" "dmul")])
1fd4e8c1
RK
3135
3136(define_insn ""
cd2b37d9
RK
3137 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3138 (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3139 (match_operand:SF 2 "gpc_reg_operand" "f"))
3140 (match_operand:SF 3 "gpc_reg_operand" "f")))]
38c1f2d7 3141 "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
b26c8351 3142 "fmsubs %0,%1,%2,%3"
ca7f5001
RK
3143 [(set_attr "type" "fp")])
3144
3145(define_insn ""
3146 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3147 (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3148 (match_operand:SF 2 "gpc_reg_operand" "f"))
3149 (match_operand:SF 3 "gpc_reg_operand" "f")))]
38c1f2d7 3150 "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
b26c8351 3151 "{fms|fmsub} %0,%1,%2,%3"
cf27b467 3152 [(set_attr "type" "dmul")])
1fd4e8c1
RK
3153
3154(define_insn ""
cd2b37d9
RK
3155 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3156 (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3157 (match_operand:SF 2 "gpc_reg_operand" "f"))
3158 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
38c1f2d7 3159 "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
b26c8351 3160 "fnmadds %0,%1,%2,%3"
ca7f5001
RK
3161 [(set_attr "type" "fp")])
3162
3163(define_insn ""
3164 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3165 (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3166 (match_operand:SF 2 "gpc_reg_operand" "f"))
3167 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
38c1f2d7 3168 "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
b26c8351 3169 "{fnma|fnmadd} %0,%1,%2,%3"
cf27b467 3170 [(set_attr "type" "dmul")])
1fd4e8c1
RK
3171
3172(define_insn ""
cd2b37d9
RK
3173 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3174 (neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3175 (match_operand:SF 2 "gpc_reg_operand" "f"))
3176 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
38c1f2d7 3177 "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
b26c8351 3178 "fnmsubs %0,%1,%2,%3"
ca7f5001
RK
3179 [(set_attr "type" "fp")])
3180
3181(define_insn ""
3182 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3183 (neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3184 (match_operand:SF 2 "gpc_reg_operand" "f"))
3185 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
38c1f2d7 3186 "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
b26c8351 3187 "{fnms|fnmsub} %0,%1,%2,%3"
cf27b467 3188 [(set_attr "type" "dmul")])
1fd4e8c1 3189
ca7f5001
RK
3190(define_expand "sqrtsf2"
3191 [(set (match_operand:SF 0 "gpc_reg_operand" "")
3192 (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "")))]
d14a6d05 3193 "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT"
ca7f5001
RK
3194 "")
3195
3196(define_insn ""
3197 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3198 (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
d14a6d05 3199 "TARGET_PPC_GPOPT && TARGET_HARD_FLOAT"
ca7f5001
RK
3200 "fsqrts %0,%1"
3201 [(set_attr "type" "ssqrt")])
3202
3203(define_insn ""
3204 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3205 (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
d14a6d05 3206 "TARGET_POWER2 && TARGET_HARD_FLOAT"
ca7f5001
RK
3207 "fsqrt %0,%1"
3208 [(set_attr "type" "dsqrt")])
3209
94d7001a
RK
3210;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
3211;; fsel instruction and some auxiliary computations. Then we just have a
3212;; single DEFINE_INSN for fsel and the define_splits to make them if made by
8e871c05
RK
3213;; combine.
3214(define_expand "maxsf3"
3215 [(set (match_dup 3)
3216 (minus:SF (match_operand:SF 1 "gpc_reg_operand" "")
3217 (match_operand:SF 2 "gpc_reg_operand" "")))
3218 (set (match_operand:SF 0 "gpc_reg_operand" "")
3219 (if_then_else:SF (ge (match_dup 3)
3220 (const_int 0))
3221 (match_dup 1)
3222 (match_dup 2)))]
d14a6d05 3223 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3224 "
3225{ operands[3] = gen_reg_rtx (SFmode); }")
2f607b94 3226
8e871c05
RK
3227(define_split
3228 [(set (match_operand:SF 0 "gpc_reg_operand" "")
3229 (smax:SF (match_operand:SF 1 "gpc_reg_operand" "")
f63184ac 3230 (match_operand:SF 2 "gpc_reg_operand" "")))
8e871c05 3231 (clobber (match_operand:SF 3 "gpc_reg_operand" ""))]
d14a6d05 3232 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3233 [(set (match_dup 3)
3234 (minus:SF (match_dup 1) (match_dup 2)))
a81bd72f 3235 (set (match_dup 0)
8e871c05
RK
3236 (if_then_else:SF (ge (match_dup 3)
3237 (const_int 0))
3238 (match_dup 1)
3239 (match_dup 2)))]
3240 "")
2f607b94 3241
8e871c05
RK
3242(define_expand "minsf3"
3243 [(set (match_dup 3)
3244 (minus:SF (match_operand:SF 2 "gpc_reg_operand" "")
3245 (match_operand:SF 1 "gpc_reg_operand" "")))
3246 (set (match_operand:SF 0 "gpc_reg_operand" "")
3247 (if_then_else:SF (ge (match_dup 3)
3248 (const_int 0))
3249 (match_dup 1)
3250 (match_dup 2)))]
d14a6d05 3251 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3252 "
3253{ operands[3] = gen_reg_rtx (SFmode); }")
2f607b94 3254
8e871c05
RK
3255(define_split
3256 [(set (match_operand:SF 0 "gpc_reg_operand" "")
3257 (smin:SF (match_operand:SF 1 "gpc_reg_operand" "")
f63184ac 3258 (match_operand:SF 2 "gpc_reg_operand" "")))
8e871c05 3259 (clobber (match_operand:SF 3 "gpc_reg_operand" ""))]
d14a6d05 3260 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3261 [(set (match_dup 3)
3262 (minus:SF (match_dup 2) (match_dup 1)))
a81bd72f 3263 (set (match_dup 0)
8e871c05
RK
3264 (if_then_else:SF (ge (match_dup 3)
3265 (const_int 0))
3266 (match_dup 1)
3267 (match_dup 2)))]
3268 "")
2f607b94 3269
94d7001a
RK
3270(define_expand "movsfcc"
3271 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3272 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3273 (match_operand:SF 2 "gpc_reg_operand" "f")
3274 (match_operand:SF 3 "gpc_reg_operand" "f")))]
d14a6d05 3275 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
94d7001a
RK
3276 "
3277{
3278 rtx temp, op0, op1;
3279 enum rtx_code code = GET_CODE (operands[1]);
3280 if (! rs6000_compare_fp_p)
3281 FAIL;
3282 switch (code)
3283 {
3284 case GE: case EQ: case NE:
3285 op0 = rs6000_compare_op0;
3286 op1 = rs6000_compare_op1;
3287 break;
3288 case GT:
3289 op0 = rs6000_compare_op1;
3290 op1 = rs6000_compare_op0;
3291 temp = operands[2]; operands[2] = operands[3]; operands[3] = temp;
3292 break;
3293 case LE:
3294 op0 = rs6000_compare_op1;
3295 op1 = rs6000_compare_op0;
3296 break;
3297 case LT:
3298 op0 = rs6000_compare_op0;
3299 op1 = rs6000_compare_op1;
3300 temp = operands[2]; operands[2] = operands[3]; operands[3] = temp;
3301 break;
3302 default:
3303 FAIL;
3304 }
3305 if (GET_MODE (rs6000_compare_op0) == DFmode)
3306 {
3307 temp = gen_reg_rtx (DFmode);
3308 emit_insn (gen_subdf3 (temp, op0, op1));
3309 emit_insn (gen_fseldfsf4 (operands[0], temp, operands[2], operands[3]));
3310 if (code == EQ)
3311 {
3312 emit_insn (gen_negdf2 (temp, temp));
3313 emit_insn (gen_fseldfsf4 (operands[0], temp, operands[0], operands[3]));
3314 }
3315 if (code == NE)
3316 {
3317 emit_insn (gen_negdf2 (temp, temp));
3318 emit_insn (gen_fseldfsf4 (operands[0], temp, operands[3], operands[0]));
3319 }
3320 }
3321 else
3322 {
3323 temp = gen_reg_rtx (SFmode);
3324 emit_insn (gen_subsf3 (temp, op0, op1));
3325 emit_insn (gen_fselsfsf4 (operands[0], temp, operands[2], operands[3]));
3326 if (code == EQ)
3327 {
3328 emit_insn (gen_negsf2 (temp, temp));
3329 emit_insn (gen_fselsfsf4 (operands[0], temp, operands[0], operands[3]));
3330 }
3331 if (code == NE)
3332 {
3333 emit_insn (gen_negsf2 (temp, temp));
3334 emit_insn (gen_fselsfsf4 (operands[0], temp, operands[3], operands[0]));
3335 }
3336 }
3337 DONE;
3338}")
d56d506a 3339
94d7001a 3340(define_insn "fselsfsf4"
8e871c05
RK
3341 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3342 (if_then_else:SF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
3343 (const_int 0))
3344 (match_operand:SF 2 "gpc_reg_operand" "f")
3345 (match_operand:SF 3 "gpc_reg_operand" "f")))]
d14a6d05 3346 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3347 "fsel %0,%1,%2,%3"
3348 [(set_attr "type" "fp")])
2f607b94 3349
94d7001a
RK
3350(define_insn "fseldfsf4"
3351 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3352 (if_then_else:SF (ge (match_operand:DF 1 "gpc_reg_operand" "f")
3353 (const_int 0))
3354 (match_operand:SF 2 "gpc_reg_operand" "f")
3355 (match_operand:SF 3 "gpc_reg_operand" "f")))]
d14a6d05 3356 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
94d7001a
RK
3357 "fsel %0,%1,%2,%3"
3358 [(set_attr "type" "fp")])
d56d506a 3359
1fd4e8c1 3360(define_insn "negdf2"
cd2b37d9
RK
3361 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3362 (neg:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
d14a6d05 3363 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
3364 "fneg %0,%1"
3365 [(set_attr "type" "fp")])
3366
3367(define_insn "absdf2"
cd2b37d9
RK
3368 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3369 (abs:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
d14a6d05 3370 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
3371 "fabs %0,%1"
3372 [(set_attr "type" "fp")])
3373
3374(define_insn ""
cd2b37d9
RK
3375 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3376 (neg:DF (abs:DF (match_operand:DF 1 "gpc_reg_operand" "f"))))]
d14a6d05 3377 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
3378 "fnabs %0,%1"
3379 [(set_attr "type" "fp")])
3380
3381(define_insn "adddf3"
cd2b37d9
RK
3382 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3383 (plus:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
3384 (match_operand:DF 2 "gpc_reg_operand" "f")))]
d14a6d05 3385 "TARGET_HARD_FLOAT"
ca7f5001 3386 "{fa|fadd} %0,%1,%2"
1fd4e8c1
RK
3387 [(set_attr "type" "fp")])
3388
3389(define_insn "subdf3"
cd2b37d9
RK
3390 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3391 (minus:DF (match_operand:DF 1 "gpc_reg_operand" "f")
3392 (match_operand:DF 2 "gpc_reg_operand" "f")))]
d14a6d05 3393 "TARGET_HARD_FLOAT"
ca7f5001 3394 "{fs|fsub} %0,%1,%2"
1fd4e8c1
RK
3395 [(set_attr "type" "fp")])
3396
3397(define_insn "muldf3"
cd2b37d9
RK
3398 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3399 (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
3400 (match_operand:DF 2 "gpc_reg_operand" "f")))]
d14a6d05 3401 "TARGET_HARD_FLOAT"
ca7f5001 3402 "{fm|fmul} %0,%1,%2"
cfb557c4 3403 [(set_attr "type" "dmul")])
1fd4e8c1
RK
3404
3405(define_insn "divdf3"
cd2b37d9
RK
3406 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3407 (div:DF (match_operand:DF 1 "gpc_reg_operand" "f")
3408 (match_operand:DF 2 "gpc_reg_operand" "f")))]
d14a6d05 3409 "TARGET_HARD_FLOAT"
ca7f5001 3410 "{fd|fdiv} %0,%1,%2"
cfb557c4 3411 [(set_attr "type" "ddiv")])
1fd4e8c1
RK
3412
3413(define_insn ""
cd2b37d9
RK
3414 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3415 (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
3416 (match_operand:DF 2 "gpc_reg_operand" "f"))
3417 (match_operand:DF 3 "gpc_reg_operand" "f")))]
3b7e5ef4 3418 "TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
ca7f5001 3419 "{fma|fmadd} %0,%1,%2,%3"
cfb557c4 3420 [(set_attr "type" "dmul")])
1fd4e8c1
RK
3421
3422(define_insn ""
cd2b37d9
RK
3423 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3424 (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
3425 (match_operand:DF 2 "gpc_reg_operand" "f"))
3426 (match_operand:DF 3 "gpc_reg_operand" "f")))]
3b7e5ef4 3427 "TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
ca7f5001 3428 "{fms|fmsub} %0,%1,%2,%3"
cfb557c4 3429 [(set_attr "type" "dmul")])
1fd4e8c1
RK
3430
3431(define_insn ""
cd2b37d9
RK
3432 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3433 (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
3434 (match_operand:DF 2 "gpc_reg_operand" "f"))
3435 (match_operand:DF 3 "gpc_reg_operand" "f"))))]
3b7e5ef4 3436 "TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
ca7f5001 3437 "{fnma|fnmadd} %0,%1,%2,%3"
cfb557c4 3438 [(set_attr "type" "dmul")])
1fd4e8c1
RK
3439
3440(define_insn ""
cd2b37d9
RK
3441 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3442 (neg:DF (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
3443 (match_operand:DF 2 "gpc_reg_operand" "f"))
3444 (match_operand:DF 3 "gpc_reg_operand" "f"))))]
3b7e5ef4 3445 "TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
ca7f5001 3446 "{fnms|fnmsub} %0,%1,%2,%3"
cfb557c4 3447 [(set_attr "type" "dmul")])
ca7f5001
RK
3448
3449(define_insn "sqrtdf2"
3450 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3451 (sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
d14a6d05 3452 "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT"
ca7f5001
RK
3453 "fsqrt %0,%1"
3454 [(set_attr "type" "dsqrt")])
b77dfefc 3455
94d7001a
RK
3456;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
3457;; fsel instruction and some auxiliary computations. Then we just have a
3458;; single DEFINE_INSN for fsel and the define_splits to make them if made by
8e871c05 3459;; combine.
b77dfefc 3460
8e871c05
RK
3461(define_expand "maxdf3"
3462 [(set (match_dup 3)
3463 (minus:DF (match_operand:DF 1 "gpc_reg_operand" "")
3464 (match_operand:DF 2 "gpc_reg_operand" "")))
3465 (set (match_operand:DF 0 "gpc_reg_operand" "")
3466 (if_then_else:DF (ge (match_dup 3)
3467 (const_int 0))
3468 (match_dup 1)
3469 (match_dup 2)))]
d14a6d05 3470 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3471 "
3472{ operands[3] = gen_reg_rtx (DFmode); }")
b77dfefc 3473
8e871c05
RK
3474(define_split
3475 [(set (match_operand:DF 0 "gpc_reg_operand" "")
3476 (smax:DF (match_operand:DF 1 "gpc_reg_operand" "")
f63184ac 3477 (match_operand:DF 2 "gpc_reg_operand" "")))
8e871c05 3478 (clobber (match_operand:DF 3 "gpc_reg_operand" ""))]
d14a6d05 3479 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3480 [(set (match_dup 3)
3481 (minus:DF (match_dup 1) (match_dup 2)))
a81bd72f 3482 (set (match_dup 0)
8e871c05
RK
3483 (if_then_else:DF (ge (match_dup 3)
3484 (const_int 0))
3485 (match_dup 1)
3486 (match_dup 2)))]
3487 "")
b77dfefc 3488
8e871c05
RK
3489(define_expand "mindf3"
3490 [(set (match_dup 3)
3491 (minus:DF (match_operand:DF 2 "gpc_reg_operand" "")
3492 (match_operand:DF 1 "gpc_reg_operand" "")))
3493 (set (match_operand:DF 0 "gpc_reg_operand" "")
3494 (if_then_else:DF (ge (match_dup 3)
3495 (const_int 0))
3496 (match_dup 1)
3497 (match_dup 2)))]
d14a6d05 3498 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3499 "
3500{ operands[3] = gen_reg_rtx (DFmode); }")
b77dfefc 3501
8e871c05
RK
3502(define_split
3503 [(set (match_operand:DF 0 "gpc_reg_operand" "")
3504 (smin:DF (match_operand:DF 1 "gpc_reg_operand" "")
f63184ac 3505 (match_operand:DF 2 "gpc_reg_operand" "")))
8e871c05 3506 (clobber (match_operand:DF 3 "gpc_reg_operand" ""))]
d14a6d05 3507 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3508 [(set (match_dup 3)
3509 (minus:DF (match_dup 2) (match_dup 1)))
a81bd72f 3510 (set (match_dup 0)
8e871c05
RK
3511 (if_then_else:DF (ge (match_dup 3)
3512 (const_int 0))
3513 (match_dup 1)
3514 (match_dup 2)))]
3515 "")
b77dfefc 3516
94d7001a
RK
3517(define_expand "movdfcc"
3518 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3519 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3520 (match_operand:DF 2 "gpc_reg_operand" "f")
3521 (match_operand:DF 3 "gpc_reg_operand" "f")))]
d14a6d05 3522 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
94d7001a
RK
3523 "
3524{
3525 rtx temp, op0, op1;
3526 enum rtx_code code = GET_CODE (operands[1]);
3527 if (! rs6000_compare_fp_p)
3528 FAIL;
3529 switch (code)
3530 {
3531 case GE: case EQ: case NE:
3532 op0 = rs6000_compare_op0;
3533 op1 = rs6000_compare_op1;
3534 break;
3535 case GT:
3536 op0 = rs6000_compare_op1;
3537 op1 = rs6000_compare_op0;
3538 temp = operands[2]; operands[2] = operands[3]; operands[3] = temp;
3539 break;
3540 case LE:
3541 op0 = rs6000_compare_op1;
3542 op1 = rs6000_compare_op0;
3543 break;
3544 case LT:
3545 op0 = rs6000_compare_op0;
3546 op1 = rs6000_compare_op1;
3547 temp = operands[2]; operands[2] = operands[3]; operands[3] = temp;
3548 break;
3549 default:
3550 FAIL;
3551 }
3552 if (GET_MODE (rs6000_compare_op0) == DFmode)
3553 {
3554 temp = gen_reg_rtx (DFmode);
3555 emit_insn (gen_subdf3 (temp, op0, op1));
3556 emit_insn (gen_fseldfdf4 (operands[0], temp, operands[2], operands[3]));
3557 if (code == EQ)
3558 {
3559 emit_insn (gen_negdf2 (temp, temp));
3560 emit_insn (gen_fseldfdf4 (operands[0], temp, operands[0], operands[3]));
3561 }
3562 if (code == NE)
3563 {
3564 emit_insn (gen_negdf2 (temp, temp));
3565 emit_insn (gen_fseldfdf4 (operands[0], temp, operands[3], operands[0]));
3566 }
3567 }
3568 else
3569 {
3570 temp = gen_reg_rtx (SFmode);
3571 emit_insn (gen_subsf3 (temp, op0, op1));
3572 emit_insn (gen_fselsfdf4 (operands[0], temp, operands[2], operands[3]));
3573 if (code == EQ)
3574 {
3575 emit_insn (gen_negsf2 (temp, temp));
3576 emit_insn (gen_fselsfdf4 (operands[0], temp, operands[0], operands[3]));
3577 }
3578 if (code == NE)
3579 {
3580 emit_insn (gen_negsf2 (temp, temp));
3581 emit_insn (gen_fselsfdf4 (operands[0], temp, operands[3], operands[0]));
3582 }
3583 }
3584 DONE;
3585}")
d56d506a 3586
94d7001a 3587(define_insn "fseldfdf4"
8e871c05
RK
3588 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3589 (if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "f")
3590 (const_int 0))
3591 (match_operand:DF 2 "gpc_reg_operand" "f")
3592 (match_operand:DF 3 "gpc_reg_operand" "f")))]
d14a6d05 3593 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3594 "fsel %0,%1,%2,%3"
3595 [(set_attr "type" "fp")])
d56d506a 3596
94d7001a
RK
3597(define_insn "fselsfdf4"
3598 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3599 (if_then_else:DF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
3600 (const_int 0))
3601 (match_operand:DF 2 "gpc_reg_operand" "f")
3602 (match_operand:DF 3 "gpc_reg_operand" "f")))]
3603 "TARGET_PPC_GFXOPT"
3604 "fsel %0,%1,%2,%3"
3605 [(set_attr "type" "fp")])
1fd4e8c1
RK
3606\f
3607;; Conversions to and from floating-point.
802a0058 3608
1fd4e8c1 3609(define_expand "floatsidf2"
802a0058
MM
3610 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
3611 (float:DF (match_operand:SI 1 "gpc_reg_operand" "")))
3612 (use (match_dup 2))
3613 (use (match_dup 3))
208c89ce 3614 (clobber (match_dup 4))
a7df97e6 3615 (clobber (match_dup 5))
802a0058 3616 (clobber (reg:DF 76))])]
a260abc9 3617 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
3618 "
3619{
802a0058
MM
3620 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
3621 operands[3] = force_reg (DFmode, rs6000_float_const (\"4503601774854144\", DFmode));
208c89ce 3622 operands[4] = gen_reg_rtx (SImode);
a7df97e6 3623 operands[5] = gen_reg_rtx (Pmode);
1fd4e8c1
RK
3624}")
3625
802a0058
MM
3626(define_insn "*floatsidf2_internal"
3627 [(set (match_operand:DF 0 "gpc_reg_operand" "=&f")
3628 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
3629 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
3630 (use (match_operand:DF 3 "gpc_reg_operand" "f"))
208c89ce 3631 (clobber (match_operand:SI 4 "gpc_reg_operand" "=r"))
a260abc9 3632 (clobber (match_operand 5 "gpc_reg_operand" "=b"))
802a0058 3633 (clobber (reg:DF 76))]
a260abc9 3634 "TARGET_HARD_FLOAT"
802a0058 3635 "#"
a7df97e6 3636 [(set_attr "length" "24")])
802a0058
MM
3637
3638(define_split
dbe3df29 3639 [(set (match_operand:DF 0 "gpc_reg_operand" "")
802a0058
MM
3640 (float:DF (match_operand:SI 1 "gpc_reg_operand" "")))
3641 (use (match_operand:SI 2 "gpc_reg_operand" ""))
3642 (use (match_operand:DF 3 "gpc_reg_operand" ""))
208c89ce 3643 (clobber (match_operand:SI 4 "gpc_reg_operand" ""))
a260abc9 3644 (clobber (match_operand 5 "gpc_reg_operand" ""))
802a0058 3645 (clobber (reg:DF 76))]
a260abc9 3646 "TARGET_HARD_FLOAT"
802a0058 3647 [(set (match_dup 4)
208c89ce 3648 (xor:SI (match_dup 1)
a7df97e6
MM
3649 (match_dup 6)))
3650 (set (match_dup 5)
3651 (unspec [(const_int 0)] 11))
3652 (set (match_dup 7)
3653 (unspec [(match_dup 4)
3654 (match_dup 5)] 12)) ;; low word
3655 (set (match_dup 7)
3656 (unspec [(match_dup 2)
3657 (match_dup 5)
3658 (match_dup 7)] 13)) ;; high word
802a0058 3659 (set (match_dup 0)
a7df97e6
MM
3660 (unspec [(match_dup 7)
3661 (match_dup 5)] 14))
802a0058
MM
3662 (set (match_dup 0)
3663 (minus:DF (match_dup 0)
3664 (match_dup 3)))]
208c89ce
MM
3665 "
3666{
a7df97e6
MM
3667 operands[6] = GEN_INT (0x80000000);
3668 operands[7] = gen_rtx (REG, DFmode, FPMEM_REGNUM);
208c89ce 3669}")
802a0058
MM
3670
3671(define_expand "floatunssidf2"
3672 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
3673 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "")))
3674 (use (match_dup 2))
3675 (use (match_dup 3))
a7df97e6 3676 (clobber (match_dup 4))
802a0058 3677 (clobber (reg:DF 76))])]
a260abc9 3678 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
3679 "
3680{
802a0058
MM
3681 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
3682 operands[3] = force_reg (DFmode, rs6000_float_const (\"4503599627370496\", DFmode));
a7df97e6 3683 operands[4] = gen_reg_rtx (Pmode);
1fd4e8c1
RK
3684}")
3685
802a0058
MM
3686(define_insn "*floatunssidf2_internal"
3687 [(set (match_operand:DF 0 "gpc_reg_operand" "=&f")
3688 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
3689 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
3690 (use (match_operand:DF 3 "gpc_reg_operand" "f"))
a260abc9 3691 (clobber (match_operand 4 "gpc_reg_operand" "=b"))
802a0058 3692 (clobber (reg:DF 76))]
a260abc9 3693 "TARGET_HARD_FLOAT"
802a0058 3694 "#"
a7df97e6 3695 [(set_attr "length" "20")])
802a0058
MM
3696
3697(define_split
3698 [(set (match_operand:DF 0 "gpc_reg_operand" "")
3699 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "")))
3700 (use (match_operand:SI 2 "gpc_reg_operand" ""))
3701 (use (match_operand:DF 3 "gpc_reg_operand" ""))
a260abc9 3702 (clobber (match_operand 4 "gpc_reg_operand" "=b"))
802a0058 3703 (clobber (reg:DF 76))]
a260abc9 3704 "TARGET_HARD_FLOAT"
802a0058 3705 [(set (match_dup 4)
a7df97e6
MM
3706 (unspec [(const_int 0)] 11))
3707 (set (match_dup 5)
3708 (unspec [(match_dup 1)
3709 (match_dup 4)] 12)) ;; low word
3710 (set (match_dup 5)
3711 (unspec [(match_dup 2)
3712 (match_dup 4)
3713 (match_dup 5)] 13)) ;; high word
802a0058 3714 (set (match_dup 0)
a7df97e6
MM
3715 (unspec [(match_dup 5)
3716 (reg:SI 1)] 14))
802a0058
MM
3717 (set (match_dup 0)
3718 (minus:DF (match_dup 0)
3719 (match_dup 3)))]
a7df97e6 3720 "operands[5] = gen_rtx (REG, DFmode, FPMEM_REGNUM);")
802a0058 3721
a7df97e6
MM
3722;; Load up scratch register with base address + offset if needed
3723(define_insn "*floatsidf2_loadaddr"
a260abc9 3724 [(set (match_operand 0 "gpc_reg_operand" "=b")
a7df97e6
MM
3725 (unspec [(const_int 0)] 11))]
3726 "TARGET_HARD_FLOAT"
3727 "*
3728{
3729 if (rs6000_fpmem_offset > 32760)
3730 {
3731 rtx xop[3];
3732
3733 xop[0] = operands[0];
3734 xop[1] = (frame_pointer_needed) ? frame_pointer_rtx : stack_pointer_rtx;
170e0690 3735 xop[2] = GEN_INT ((rs6000_fpmem_offset >> 16) + ((rs6000_fpmem_offset & 0x8000) >> 15));
538bb158 3736 output_asm_insn (\"{cau|addis} %0,%1,%2\", xop);
a7df97e6 3737 }
a7df97e6
MM
3738
3739 return \"\";
3740}"
3741 [(set_attr "length" "4")])
802a0058
MM
3742
3743(define_insn "*floatsidf2_store1"
3744 [(set (reg:DF 76)
3745 (unspec [(match_operand:SI 0 "gpc_reg_operand" "r")
a260abc9
DE
3746 (match_operand 1 "gpc_reg_operand" "b")] 12))]
3747 "TARGET_HARD_FLOAT"
802a0058 3748 "*
dbe3df29 3749{
a7df97e6
MM
3750 rtx indx;
3751
3752 if (rs6000_fpmem_offset > 32760)
3753 indx = operands[1];
3754 else if (frame_pointer_needed)
3755 indx = frame_pointer_rtx;
3756 else
3757 indx = stack_pointer_rtx;
3758
3759 operands[2] = gen_rtx (MEM, SImode,
802a0058 3760 gen_rtx (PLUS, Pmode,
a7df97e6 3761 indx,
170e0690 3762 GEN_INT ((((rs6000_fpmem_offset & 0xffff) ^ 0x8000) - 0x8000)
802a0058 3763 + ((WORDS_BIG_ENDIAN != 0) * 4))));
c283c989 3764
a7df97e6 3765 return \"{st|stw} %0,%2\";
802a0058
MM
3766}"
3767 [(set_attr "type" "store")])
3768
3769(define_insn "*floatsidf2_store2"
3770 [(set (reg:DF 76)
3771 (unspec [(match_operand:SI 0 "gpc_reg_operand" "r")
a260abc9 3772 (match_operand 1 "gpc_reg_operand" "b")
a7df97e6 3773 (reg:DF 76)] 13))]
a260abc9 3774 "TARGET_HARD_FLOAT"
802a0058
MM
3775 "*
3776{
a7df97e6
MM
3777 rtx indx;
3778
3779 if (rs6000_fpmem_offset > 32760)
3780 indx = operands[1];
3781 else if (frame_pointer_needed)
3782 indx = frame_pointer_rtx;
3783 else
3784 indx = stack_pointer_rtx;
3785
3786 operands[2] = gen_rtx (MEM, SImode,
802a0058 3787 gen_rtx (PLUS, Pmode,
a7df97e6 3788 indx,
170e0690 3789 GEN_INT ((((rs6000_fpmem_offset & 0xffff) ^ 0x8000) - 0x8000)
802a0058
MM
3790 + ((WORDS_BIG_ENDIAN == 0) * 4))));
3791
a7df97e6 3792 return \"{st|stw} %0,%2\";
802a0058
MM
3793}"
3794 [(set_attr "type" "store")])
3795
3796(define_insn "*floatsidf2_load"
3797 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3798 (unspec [(reg:DF 76)
a260abc9
DE
3799 (match_operand 1 "gpc_reg_operand" "b")] 14))]
3800 "TARGET_HARD_FLOAT"
802a0058
MM
3801 "*
3802{
a7df97e6 3803 rtx indx;
f6968f59 3804 HOST_WIDE_INT offset = rs6000_fpmem_offset;
a7df97e6
MM
3805
3806 if (rs6000_fpmem_offset > 32760)
f6968f59
MM
3807 {
3808 indx = operands[1];
170e0690 3809 offset = (((offset & 0xffff) ^ 0x8000) - 0x8000);
f6968f59 3810 }
a7df97e6
MM
3811 else if (frame_pointer_needed)
3812 indx = frame_pointer_rtx;
3813 else
3814 indx = stack_pointer_rtx;
3815
3816 operands[2] = gen_rtx (MEM, SImode,
f6968f59 3817 gen_rtx (PLUS, Pmode, indx, GEN_INT (offset)));
802a0058 3818
a7df97e6 3819 return \"lfd %0,%2\";
802a0058
MM
3820}"
3821 [(set_attr "type" "fpload")])
1fd4e8c1 3822
1fd4e8c1 3823(define_expand "fix_truncdfsi2"
802a0058
MM
3824 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
3825 (fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))
3826 (clobber (match_dup 2))
a7df97e6
MM
3827 (clobber (match_dup 3))
3828 (clobber (match_dup 4))])]
d14a6d05 3829 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
3830 "
3831{
802a0058 3832 if (!TARGET_POWER2 && !TARGET_POWERPC)
8ffd9c51
RK
3833 {
3834 emit_insn (gen_trunc_call (operands[0], operands[1],
3835 gen_rtx (SYMBOL_REF, Pmode, RS6000_ITRUNC)));
3836 DONE;
3837 }
802a0058
MM
3838
3839 operands[2] = gen_reg_rtx (DImode);
a7df97e6
MM
3840 operands[3] = gen_reg_rtx (Pmode);
3841 operands[4] = gen_rtx (REG, DImode, FPMEM_REGNUM);
1fd4e8c1
RK
3842}")
3843
802a0058
MM
3844(define_insn "*fix_truncdfsi2_internal"
3845 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3846 (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))
3847 (clobber (match_operand:DI 2 "gpc_reg_operand" "=f"))
a260abc9 3848 (clobber (match_operand 3 "gpc_reg_operand" "=b"))
802a0058
MM
3849 (clobber (reg:DI 76))]
3850 "TARGET_HARD_FLOAT"
3851 "#"
3852 [(set_attr "length" "12")])
3853
3854(define_split
3855 [(set (match_operand:SI 0 "gpc_reg_operand" "")
3856 (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))
3857 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
a260abc9 3858 (clobber (match_operand 3 "gpc_reg_operand" ""))
802a0058
MM
3859 (clobber (reg:DI 76))]
3860 "TARGET_HARD_FLOAT"
3861 [(set (match_dup 2)
3862 (sign_extend:DI (fix:SI (match_operand:DF 1 "gpc_reg_operand" ""))))
3863 (set (match_dup 3)
a7df97e6
MM
3864 (unspec [(const_int 0)] 11))
3865 (set (match_dup 4)
802a0058 3866 (unspec [(match_dup 2)
a7df97e6 3867 (match_dup 3)] 15))
802a0058 3868 (set (match_operand:SI 0 "gpc_reg_operand" "")
a7df97e6
MM
3869 (unspec [(match_dup 4)
3870 (match_dup 3)] 16))]
3871 "operands[4] = gen_rtx (REG, DImode, FPMEM_REGNUM);")
802a0058 3872
802a0058
MM
3873(define_insn "*fix_truncdfsi2_store"
3874 [(set (reg:DI 76)
3875 (unspec [(match_operand:DI 0 "gpc_reg_operand" "f")
a260abc9 3876 (match_operand 1 "gpc_reg_operand" "b")] 15))]
802a0058
MM
3877 "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT"
3878 "*
3879{
a7df97e6
MM
3880 rtx indx;
3881
3882 if (rs6000_fpmem_offset > 32760)
3883 indx = operands[1];
3884 else if (frame_pointer_needed)
3885 indx = frame_pointer_rtx;
3886 else
3887 indx = stack_pointer_rtx;
3888
3889 operands[2] = gen_rtx (MEM, DFmode,
802a0058 3890 gen_rtx (PLUS, Pmode,
a7df97e6 3891 indx,
eaf1bcf1
MM
3892 GEN_INT ((((rs6000_fpmem_offset & 0xffff)
3893 ^ 0x8000) - 0x8000))));
802a0058 3894
170e0690 3895 return \"stfd %0,%w2\";
802a0058
MM
3896}"
3897 [(set_attr "type" "fpstore")])
3898
3899(define_insn "*fix_truncdfsi2_load"
3900 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3901 (unspec [(reg:DI 76)
a260abc9 3902 (match_operand 1 "gpc_reg_operand" "b")] 16))]
802a0058
MM
3903 "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT"
3904 "*
3905{
a7df97e6
MM
3906 rtx indx;
3907
3908 if (rs6000_fpmem_offset > 32760)
3909 indx = operands[1];
3910 else if (frame_pointer_needed)
3911 indx = frame_pointer_rtx;
3912 else
3913 indx = stack_pointer_rtx;
3914
3915 operands[2] = gen_rtx (MEM, DFmode,
802a0058 3916 gen_rtx (PLUS, Pmode,
a7df97e6 3917 indx,
170e0690 3918 GEN_INT ((((rs6000_fpmem_offset & 0xffff) ^ 0x8000) - 0x8000)
a7df97e6 3919 + ((WORDS_BIG_ENDIAN) ? 4 : 0))));
802a0058 3920
a7df97e6 3921 return \"{l|lwz} %0,%2\";
802a0058
MM
3922}"
3923 [(set_attr "type" "load")])
3924
1fd4e8c1 3925(define_expand "fixuns_truncdfsi2"
cd2b37d9 3926 [(set (match_operand:SI 0 "gpc_reg_operand" "")
b542afe9 3927 (unsigned_fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))]
d14a6d05 3928 "! TARGET_POWER2 && ! TARGET_POWERPC && TARGET_HARD_FLOAT"
1fd4e8c1
RK
3929 "
3930{
3931 emit_insn (gen_trunc_call (operands[0], operands[1],
3c64f04b 3932 gen_rtx (SYMBOL_REF, Pmode, RS6000_UITRUNC)));
1fd4e8c1
RK
3933 DONE;
3934}")
3935
1fd4e8c1
RK
3936(define_expand "trunc_call"
3937 [(parallel [(set (match_operand:SI 0 "" "")
b542afe9 3938 (fix:SI (match_operand:DF 1 "" "")))
1fd4e8c1 3939 (use (match_operand:SI 2 "" ""))])]
d14a6d05 3940 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
3941 "
3942{
3943 rtx insns = gen_trunc_call_rtl (operands[0], operands[1], operands[2]);
3944 rtx first = XVECEXP (insns, 0, 0);
3945 rtx last = XVECEXP (insns, 0, XVECLEN (insns, 0) - 1);
3946
3947 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
3948 REG_NOTES (first));
3949 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
3950
3951 emit_insn (insns);
3952 DONE;
3953}")
3954
3955(define_expand "trunc_call_rtl"
cd2b37d9 3956 [(set (reg:DF 33) (match_operand:DF 1 "gpc_reg_operand" ""))
1fd4e8c1
RK
3957 (use (reg:DF 33))
3958 (parallel [(set (reg:SI 3)
3959 (call (mem:SI (match_operand 2 "" "")) (const_int 0)))
4697a36c 3960 (use (const_int 0))
1fd4e8c1 3961 (clobber (scratch:SI))])
cd2b37d9 3962 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1 3963 (reg:SI 3))]
d14a6d05 3964 "TARGET_HARD_FLOAT"
1fd4e8c1 3965 "
7e69e155 3966{
1fd4e8c1
RK
3967 rs6000_trunc_used = 1;
3968}")
a473029f 3969
a260abc9
DE
3970(define_insn "*fctiwz"
3971 [(set (match_operand:DI 0 "gpc_reg_operand" "=f")
3972 (sign_extend:DI (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))))]
3973 "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT"
3974 "{fcirz|fctiwz} %0,%1"
3975 [(set_attr "type" "fp")])
3976
a473029f
RK
3977(define_insn "floatdidf2"
3978 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3979 (float:DF (match_operand:DI 1 "gpc_reg_operand" "f")))]
d14a6d05 3980 "TARGET_POWERPC64 && TARGET_HARD_FLOAT"
a473029f
RK
3981 "fcfid %0,%1"
3982 [(set_attr "type" "fp")])
3983
3984(define_insn "fix_truncdfdi2"
3985 [(set (match_operand:DI 0 "gpc_reg_operand" "=f")
3986 (fix:DI (match_operand:DF 1 "gpc_reg_operand" "f")))]
d14a6d05 3987 "TARGET_POWERPC64 && TARGET_HARD_FLOAT"
a473029f
RK
3988 "fctidz %0,%1"
3989 [(set_attr "type" "fp")])
1fd4e8c1
RK
3990\f
3991;; Define the DImode operations that can be done in a small number
a6ec530c
RK
3992;; of instructions. The & constraints are to prevent the register
3993;; allocator from allocating registers that overlap with the inputs
3994;; (for example, having an input in 7,8 and an output in 6,7). We
38e01259 3995;; also allow for the output being the same as one of the inputs.
a6ec530c 3996
266eb58a 3997(define_insn "*adddi3_noppc64"
a6ec530c
RK
3998 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r,r,r")
3999 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,0,0")
4000 (match_operand:DI 2 "reg_or_short_operand" "r,I,r,I")))]
e1f83b4d 4001 "! TARGET_POWERPC64"
0f645302
MM
4002 "*
4003{
4004 if (WORDS_BIG_ENDIAN)
4005 return (GET_CODE (operands[2])) != CONST_INT
4006 ? \"{a|addc} %L0,%L1,%L2\;{ae|adde} %0,%1,%2\"
4007 : \"{ai|addic} %L0,%L1,%2\;{a%G2e|add%G2e} %0,%1\";
4008 else
4009 return (GET_CODE (operands[2])) != CONST_INT
4010 ? \"{a|addc} %0,%1,%2\;{ae|adde} %L0,%L1,%L2\"
4011 : \"{ai|addic} %0,%1,%2\;{a%G2e|add%G2e} %L0,%L1\";
4012}"
b19003d8 4013 [(set_attr "length" "8")])
1fd4e8c1 4014
266eb58a 4015(define_insn "*subdi3_noppc64"
e7e5df70
RK
4016 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r,r,r,r")
4017 (minus:DI (match_operand:DI 1 "reg_or_short_operand" "r,I,0,r,I")
4018 (match_operand:DI 2 "gpc_reg_operand" "r,r,r,0,0")))]
266eb58a 4019 "! TARGET_POWERPC64"
5502823b
RK
4020 "*
4021{
0f645302
MM
4022 if (WORDS_BIG_ENDIAN)
4023 return (GET_CODE (operands[1]) != CONST_INT)
4024 ? \"{sf|subfc} %L0,%L2,%L1\;{sfe|subfe} %0,%2,%1\"
4025 : \"{sfi|subfic} %L0,%L2,%1\;{sf%G1e|subf%G1e} %0,%2\";
4026 else
4027 return (GET_CODE (operands[1]) != CONST_INT)
4028 ? \"{sf|subfc} %0,%2,%1\;{sfe|subfe} %L0,%L2,%L1\"
4029 : \"{sfi|subfic} %0,%2,%1\;{sf%G1e|subf%G1e} %L0,%L2\";
5502823b 4030}"
ca7f5001
RK
4031 [(set_attr "length" "8")])
4032
266eb58a 4033(define_insn "*negdi2_noppc64"
a6ec530c
RK
4034 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
4035 (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))]
51b8fc2c 4036 "! TARGET_POWERPC64"
5502823b
RK
4037 "*
4038{
4039 return (WORDS_BIG_ENDIAN)
4040 ? \"{sfi|subfic} %L0,%L1,0\;{sfze|subfze} %0,%1\"
4041 : \"{sfi|subfic} %0,%1,0\;{sfze|subfze} %L0,%L1\";
4042}"
ca7f5001
RK
4043 [(set_attr "length" "8")])
4044
8ffd9c51
RK
4045(define_expand "mulsidi3"
4046 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4047 (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
4048 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))]
4049 ""
4050 "
4051{
4052 if (! TARGET_POWER && ! TARGET_POWERPC)
4053 {
4c0c634c
MM
4054 emit_move_insn (gen_rtx (REG, SImode, 3), operands[1]);
4055 emit_move_insn (gen_rtx (REG, SImode, 4), operands[2]);
fada905b 4056 emit_insn (gen_mull_call ());
cf27b467
MM
4057 if (WORDS_BIG_ENDIAN)
4058 emit_move_insn (operands[0], gen_rtx (REG, DImode, 3));
4059 else
4060 {
4061 emit_move_insn (operand_subword (operands[0], 0, 0, DImode),
4062 gen_rtx (REG, SImode, 3));
4063 emit_move_insn (operand_subword (operands[0], 1, 0, DImode),
4064 gen_rtx (REG, SImode, 4));
4065 }
8ffd9c51
RK
4066 DONE;
4067 }
4068 else if (TARGET_POWER)
4069 {
4070 emit_insn (gen_mulsidi3_mq (operands[0], operands[1], operands[2]));
4071 DONE;
4072 }
4073}")
deb9225a 4074
8ffd9c51 4075(define_insn "mulsidi3_mq"
cd2b37d9 4076 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
8ffd9c51 4077 (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
cd2b37d9 4078 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))
1fd4e8c1 4079 (clobber (match_scratch:SI 3 "=q"))]
ca7f5001 4080 "TARGET_POWER"
b19003d8 4081 "mul %0,%1,%2\;mfmq %L0"
8ffd9c51
RK
4082 [(set_attr "type" "imul")
4083 (set_attr "length" "8")])
deb9225a 4084
f192bf8b 4085(define_insn "*mulsidi3_no_mq"
425c176f 4086 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
8ffd9c51
RK
4087 (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
4088 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
f192bf8b 4089 "TARGET_POWERPC && ! TARGET_POWER && ! TARGET_POWERPC64"
5502823b
RK
4090 "*
4091{
4092 return (WORDS_BIG_ENDIAN)
4093 ? \"mulhw %0,%1,%2\;mullw %L0,%1,%2\"
4094 : \"mulhw %L0,%1,%2\;mullw %0,%1,%2\";
4095}"
8ffd9c51
RK
4096 [(set_attr "type" "imul")
4097 (set_attr "length" "8")])
deb9225a 4098
ebedb4dd
MM
4099(define_split
4100 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4101 (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
4102 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))]
cf27b467 4103 "TARGET_POWERPC && ! TARGET_POWERPC64 && reload_completed"
ebedb4dd
MM
4104 [(set (match_dup 3)
4105 (truncate:SI
4106 (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
4107 (sign_extend:DI (match_dup 2)))
4108 (const_int 32))))
4109 (set (match_dup 4)
4110 (mult:SI (match_dup 1)
4111 (match_dup 2)))]
4112 "
4113{
4114 int endian = (WORDS_BIG_ENDIAN == 0);
4115 operands[3] = operand_subword (operands[0], endian, 0, DImode);
4116 operands[4] = operand_subword (operands[0], 1 - endian, 0, DImode);
4117}")
4118
f192bf8b
DE
4119(define_expand "umulsidi3"
4120 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4121 (mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
4122 (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))]
4123 "TARGET_POWERPC && ! TARGET_POWERPC64"
4124 "
4125{
4126 if (TARGET_POWER)
4127 {
4128 emit_insn (gen_umulsidi3_mq (operands[0], operands[1], operands[2]));
4129 DONE;
4130 }
4131}")
4132
4133(define_insn "umulsidi3_mq"
4134 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
4135 (mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
4136 (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))
4137 (clobber (match_scratch:SI 3 "=q"))]
4138 "TARGET_POWERPC && TARGET_POWER"
4139 "*
4140{
4141 return (WORDS_BIG_ENDIAN)
4142 ? \"mulhwu %0,%1,%2\;mullw %L0,%1,%2\"
4143 : \"mulhwu %L0,%1,%2\;mullw %0,%1,%2\";
4144}"
4145 [(set_attr "type" "imul")
4146 (set_attr "length" "8")])
4147
4148(define_insn "*umulsidi3_no_mq"
8106dc08
MM
4149 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
4150 (mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
4151 (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
f192bf8b 4152 "TARGET_POWERPC && ! TARGET_POWER && ! TARGET_POWERPC64"
8106dc08
MM
4153 "*
4154{
4155 return (WORDS_BIG_ENDIAN)
4156 ? \"mulhwu %0,%1,%2\;mullw %L0,%1,%2\"
4157 : \"mulhwu %L0,%1,%2\;mullw %0,%1,%2\";
4158}"
4159 [(set_attr "type" "imul")
4160 (set_attr "length" "8")])
4161
ebedb4dd
MM
4162(define_split
4163 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4164 (mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
4165 (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))]
cf27b467 4166 "TARGET_POWERPC && ! TARGET_POWERPC64 && reload_completed"
ebedb4dd
MM
4167 [(set (match_dup 3)
4168 (truncate:SI
4169 (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
4170 (zero_extend:DI (match_dup 2)))
4171 (const_int 32))))
4172 (set (match_dup 4)
4173 (mult:SI (match_dup 1)
4174 (match_dup 2)))]
4175 "
4176{
4177 int endian = (WORDS_BIG_ENDIAN == 0);
4178 operands[3] = operand_subword (operands[0], endian, 0, DImode);
4179 operands[4] = operand_subword (operands[0], 1 - endian, 0, DImode);
4180}")
4181
8ffd9c51
RK
4182(define_expand "smulsi3_highpart"
4183 [(set (match_operand:SI 0 "gpc_reg_operand" "")
4184 (truncate:SI
4185 (lshiftrt:DI (mult:DI (sign_extend:DI
4186 (match_operand:SI 1 "gpc_reg_operand" "%r"))
4187 (sign_extend:DI
4188 (match_operand:SI 2 "gpc_reg_operand" "r")))
4189 (const_int 32))))]
4190 ""
4191 "
4192{
4193 if (! TARGET_POWER && ! TARGET_POWERPC)
4194 {
4195 emit_move_insn (gen_rtx (REG, SImode, 3), operands[1]);
4196 emit_move_insn (gen_rtx (REG, SImode, 4), operands[2]);
fada905b 4197 emit_insn (gen_mulh_call ());
8ffd9c51
RK
4198 emit_move_insn (operands[0], gen_rtx (REG, SImode, 3));
4199 DONE;
4200 }
4201 else if (TARGET_POWER)
4202 {
4203 emit_insn (gen_smulsi3_highpart_mq (operands[0], operands[1], operands[2]));
4204 DONE;
4205 }
4206}")
deb9225a 4207
8ffd9c51
RK
4208(define_insn "smulsi3_highpart_mq"
4209 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4210 (truncate:SI
fada905b
MM
4211 (lshiftrt:DI (mult:DI (sign_extend:DI
4212 (match_operand:SI 1 "gpc_reg_operand" "%r"))
4213 (sign_extend:DI
4214 (match_operand:SI 2 "gpc_reg_operand" "r")))
8ffd9c51
RK
4215 (const_int 32))))
4216 (clobber (match_scratch:SI 3 "=q"))]
4217 "TARGET_POWER"
4218 "mul %0,%1,%2"
4219 [(set_attr "type" "imul")])
deb9225a 4220
f192bf8b 4221(define_insn "*smulsi3_highpart_no_mq"
8ffd9c51
RK
4222 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4223 (truncate:SI
fada905b
MM
4224 (lshiftrt:DI (mult:DI (sign_extend:DI
4225 (match_operand:SI 1 "gpc_reg_operand" "%r"))
4226 (sign_extend:DI
4227 (match_operand:SI 2 "gpc_reg_operand" "r")))
8ffd9c51 4228 (const_int 32))))]
f192bf8b 4229 "TARGET_POWERPC && ! TARGET_POWER"
8ffd9c51
RK
4230 "mulhw %0,%1,%2"
4231 [(set_attr "type" "imul")])
deb9225a 4232
f192bf8b
DE
4233(define_expand "umulsi3_highpart"
4234 [(set (match_operand:SI 0 "gpc_reg_operand" "")
4235 (truncate:SI
4236 (lshiftrt:DI (mult:DI (zero_extend:DI
4237 (match_operand:SI 1 "gpc_reg_operand" ""))
4238 (zero_extend:DI
4239 (match_operand:SI 2 "gpc_reg_operand" "")))
4240 (const_int 32))))]
4241 "TARGET_POWERPC"
4242 "
4243{
4244 if (TARGET_POWER)
4245 {
4246 emit_insn (gen_umulsi3_highpart_mq (operands[0], operands[1], operands[2]));
4247 DONE;
4248 }
4249}")
4250
4251(define_insn "umulsi3_highpart_mq"
4252 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4253 (truncate:SI
4254 (lshiftrt:DI (mult:DI (zero_extend:DI
4255 (match_operand:SI 1 "gpc_reg_operand" "%r"))
4256 (zero_extend:DI
4257 (match_operand:SI 2 "gpc_reg_operand" "r")))
4258 (const_int 32))))
4259 (clobber (match_scratch:SI 3 "=q"))]
4260 "TARGET_POWERPC && TARGET_POWER"
4261 "mulhwu %0,%1,%2"
4262 [(set_attr "type" "imul")])
4263
4264(define_insn "*umulsi3_highpart_no_mq"
266eb58a
DE
4265 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4266 (truncate:SI
4267 (lshiftrt:DI (mult:DI (zero_extend:DI
4268 (match_operand:SI 1 "gpc_reg_operand" "%r"))
4269 (zero_extend:DI
4270 (match_operand:SI 2 "gpc_reg_operand" "r")))
4271 (const_int 32))))]
f192bf8b 4272 "TARGET_POWERPC && ! TARGET_POWER"
266eb58a
DE
4273 "mulhwu %0,%1,%2"
4274 [(set_attr "type" "imul")])
4275
4276;; If operands 0 and 2 are in the same register, we have a problem. But
4277;; operands 0 and 1 (the usual case) can be in the same register. That's
4278;; why we have the strange constraints below.
4279(define_insn "ashldi3_power"
4280 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,&r")
4281 (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,0,r")
4282 (match_operand:SI 2 "reg_or_cint_operand" "M,i,r,r")))
4283 (clobber (match_scratch:SI 3 "=X,q,q,q"))]
4284 "TARGET_POWER"
4285 "@
4286 {sli|slwi} %0,%L1,%h2\;{cal %L0,0(0)|li %L0,0}
4287 sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2
4288 sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2
4289 sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2"
4290 [(set_attr "length" "8")])
4291
4292(define_insn "lshrdi3_power"
47ad8c61 4293 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,&r")
266eb58a
DE
4294 (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,0,r")
4295 (match_operand:SI 2 "reg_or_cint_operand" "M,i,r,r")))
4296 (clobber (match_scratch:SI 3 "=X,q,q,q"))]
4297 "TARGET_POWER"
4298 "@
47ad8c61 4299 {s%A2i|s%A2wi} %L0,%1,%h2\;{cal %0,0(0)|li %0,0}
266eb58a
DE
4300 sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2
4301 sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2
4302 sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2"
4303 [(set_attr "length" "8")])
4304
4305;; Shift by a variable amount is too complex to be worth open-coding. We
4306;; just handle shifts by constants.
4307(define_insn "ashrdi3_power"
7093ddee 4308 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
266eb58a
DE
4309 (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
4310 (match_operand:SI 2 "const_int_operand" "M,i")))
4311 (clobber (match_scratch:SI 3 "=X,q"))]
4312 "TARGET_POWER"
4313 "@
4314 {srai|srawi} %0,%1,31\;{srai|srawi} %L0,%1,%h2
4315 sraiq %0,%1,%h2\;srliq %L0,%L1,%h2"
4316 [(set_attr "length" "8")])
4317\f
4318;; PowerPC64 DImode operations.
4319
4320(define_expand "adddi3"
4321 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4322 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "")
a260abc9 4323 (match_operand:DI 2 "reg_or_cint_operand" "")))]
266eb58a
DE
4324 ""
4325 "
4326{
a260abc9
DE
4327 if (! TARGET_POWERPC64)
4328 {
4329 if (non_short_cint_operand (operands[2], DImode))
4330 FAIL;
4331 }
4332 else
4333 if (GET_CODE (operands[2]) == CONST_INT
4334 && !add_operand (operands[2], DImode))
4335 {
4336 rtx tmp = ((reload_in_progress || reload_completed
4337 || rtx_equal_p (operands[0], operands[1]))
4338 ? operands[0] : gen_reg_rtx (DImode));
4339
4340 HOST_WIDE_INT low = INTVAL (operands[2]) & 0xffff;
4341 HOST_WIDE_INT high = INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff);
4342
4343 if (low & 0x8000)
4344 high += 0x10000, low |= ((HOST_WIDE_INT) -1) << 16;
4345
4346 emit_insn (gen_adddi3 (tmp, operands[1], GEN_INT (high)));
4347 emit_insn (gen_adddi3 (operands[0], tmp, GEN_INT (low)));
4348 DONE;
4349 }
266eb58a
DE
4350}")
4351
4352;; Discourage ai/addic because of carry but provide it in an alternative
4353;; allowing register zero as source.
4354
a260abc9 4355(define_insn "*adddi3_internal1"
266eb58a
DE
4356 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,?r,r")
4357 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,b,r,b")
4358 (match_operand:DI 2 "add_operand" "r,I,I,J")))]
4359 "TARGET_POWERPC64"
4360 "@
4361 add %0,%1,%2
4362 addi %0,%1,%2
4363 addic %0,%1,%2
802a0058 4364 addis %0,%1,%v2")
266eb58a 4365
a260abc9 4366(define_insn "*adddi3_internal2"
266eb58a
DE
4367 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
4368 (compare:CC (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
4369 (match_operand:DI 2 "reg_or_short_operand" "r,I"))
4370 (const_int 0)))
4371 (clobber (match_scratch:DI 3 "=r,r"))]
4372 "TARGET_POWERPC64"
4373 "@
4374 add. %3,%1,%2
4375 addic. %3,%1,%2"
4376 [(set_attr "type" "compare")])
4377
a260abc9 4378(define_insn "*adddi3_internal3"
266eb58a
DE
4379 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
4380 (compare:CC (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
4381 (match_operand:DI 2 "reg_or_short_operand" "r,I"))
4382 (const_int 0)))
4383 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4384 (plus:DI (match_dup 1) (match_dup 2)))]
4385 "TARGET_POWERPC64"
4386 "@
4387 add. %0,%1,%2
4388 addic. %0,%1,%2"
4389 [(set_attr "type" "compare")])
4390
4391;; Split an add that we can't do in one insn into two insns, each of which
4392;; does one 16-bit part. This is used by combine. Note that the low-order
4393;; add should be last in case the result gets used in an address.
4394
4395(define_split
4396 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4397 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "")
4398 (match_operand:DI 2 "non_add_cint_operand" "")))]
4399 "TARGET_POWERPC64"
4400 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 3)))
4401 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
4402"
4403{
e6ca2c17
DE
4404 HOST_WIDE_INT low = INTVAL (operands[2]) & 0xffff;
4405 HOST_WIDE_INT high = INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff);
266eb58a
DE
4406
4407 if (low & 0x8000)
e6ca2c17 4408 high+=0x10000, low |= ((HOST_WIDE_INT) -1) << 16;
266eb58a 4409
e6ca2c17
DE
4410 operands[3] = GEN_INT (high);
4411 operands[4] = GEN_INT (low);
266eb58a
DE
4412}")
4413
4414(define_insn "one_cmpldi2"
4415 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4416 (not:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
4417 "TARGET_POWERPC64"
4418 "nor %0,%1,%1")
4419
4420(define_insn ""
4421 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4422 (compare:CC (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4423 (const_int 0)))
4424 (clobber (match_scratch:DI 2 "=r"))]
4425 "TARGET_POWERPC64"
4426 "nor. %2,%1,%1"
4427 [(set_attr "type" "compare")])
4428
4429(define_insn ""
4430 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
4431 (compare:CC (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4432 (const_int 0)))
4433 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4434 (not:DI (match_dup 1)))]
4435 "TARGET_POWERPC64"
d944f453 4436 "nor. %0,%1,%1"
266eb58a
DE
4437 [(set_attr "type" "compare")])
4438
4439(define_insn ""
4440 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4441 (minus:DI (match_operand:DI 1 "reg_or_short_operand" "r,I")
4442 (match_operand:DI 2 "gpc_reg_operand" "r,r")))]
4443 "TARGET_POWERPC64"
4444 "@
4445 subf %0,%2,%1
4446 subfic %0,%2,%1")
4447
4448(define_insn ""
4449 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4450 (compare:CC (minus:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4451 (match_operand:DI 2 "gpc_reg_operand" "r"))
4452 (const_int 0)))
4453 (clobber (match_scratch:DI 3 "=r"))]
4454 "TARGET_POWERPC64"
4455 "subf. %3,%2,%1"
4456 [(set_attr "type" "compare")])
4457
4458(define_insn ""
4459 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4460 (compare:CC (minus:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4461 (match_operand:DI 2 "gpc_reg_operand" "r"))
4462 (const_int 0)))
4463 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4464 (minus:DI (match_dup 1) (match_dup 2)))]
4465 "TARGET_POWERPC64"
4466 "subf. %0,%2,%1"
4467 [(set_attr "type" "compare")])
4468
4469(define_expand "subdi3"
4470 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4471 (minus:DI (match_operand:DI 1 "reg_or_short_operand" "")
4472 (match_operand:DI 2 "reg_or_cint_operand" "")))]
4473 ""
4474 "
4475{
4476 if (GET_CODE (operands[2]) == CONST_INT)
4477 {
4478 emit_insn (gen_adddi3 (operands[0], operands[1],
4479 negate_rtx (DImode, operands[2])));
4480 DONE;
4481 }
4482}")
4483
4484(define_insn "absdi2"
4485 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
4486 (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))
4487 (clobber (match_scratch:DI 2 "=&r,&r"))]
4488 "TARGET_POWERPC64"
a260abc9 4489 "sradi %2,%1,63\;xor %0,%2,%1\;subf %0,%2,%0"
266eb58a
DE
4490 [(set_attr "length" "12")])
4491
4492(define_split
4493 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
4494 (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))
4495 (clobber (match_scratch:DI 2 "=&r,&r"))]
4496 "TARGET_POWERPC64 && reload_completed"
a260abc9 4497 [(set (match_dup 2) (ashiftrt:DI (match_dup 1) (const_int 63)))
266eb58a
DE
4498 (set (match_dup 0) (xor:DI (match_dup 2) (match_dup 1)))
4499 (set (match_dup 0) (minus:DI (match_dup 2) (match_dup 0)))]
4500 "")
4501
4502(define_insn ""
4503 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
4504 (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0"))))
4505 (clobber (match_scratch:DI 2 "=&r,&r"))]
4506 "TARGET_POWERPC64"
a260abc9 4507 "sradi %2,%1,63\;xor %0,%2,%1\;subf %0,%0,%2"
266eb58a
DE
4508 [(set_attr "length" "12")])
4509
4510(define_split
4511 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
4512 (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0"))))
4513 (clobber (match_scratch:DI 2 "=&r,&r"))]
4514 "TARGET_POWERPC64 && reload_completed"
a260abc9 4515 [(set (match_dup 2) (ashiftrt:DI (match_dup 1) (const_int 63)))
266eb58a
DE
4516 (set (match_dup 0) (xor:DI (match_dup 2) (match_dup 1)))
4517 (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 2)))]
4518 "")
4519
4520(define_expand "negdi2"
4521 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4522 (neg:DI (match_operand:DI 1 "gpc_reg_operand" "")))]
4523 ""
4524 "")
4525
4526(define_insn ""
4527 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4528 (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
4529 "TARGET_POWERPC64"
4530 "neg %0,%1")
4531
4532(define_insn ""
4533 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4534 (compare:CC (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4535 (const_int 0)))
4536 (clobber (match_scratch:DI 2 "=r"))]
4537 "TARGET_POWERPC64"
4538 "neg. %2,%1"
4539 [(set_attr "type" "compare")])
4540
4541(define_insn ""
4542 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
4543 (compare:CC (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4544 (const_int 0)))
4545 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4546 (neg:DI (match_dup 1)))]
4547 "TARGET_POWERPC64"
4548 "neg. %0,%1"
4549 [(set_attr "type" "compare")])
4550
4551(define_insn "ffsdi2"
4552 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
4553 (ffs:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
4554 "TARGET_POWERPC64"
4555 "neg %0,%1\;and %0,%0,%1\;cntlzd %0,%0\;subfic %0,%0,64"
4556 [(set_attr "length" "16")])
4557
4558(define_insn "muldi3"
4559 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4560 (mult:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4561 (match_operand:DI 2 "gpc_reg_operand" "r")))]
4562 "TARGET_POWERPC64"
4563 "mulld %0,%1,%2"
4564 [(set_attr "type" "imul")])
4565
a260abc9
DE
4566(define_insn "*mulsidi3_ppc64"
4567 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4568 (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
4569 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
4570 "TARGET_POWERPC64"
4571 "mulld %0,%1,%2"
4572 [(set_attr "type" "imul")])
4573
266eb58a
DE
4574(define_insn "smuldi3_highpart"
4575 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4576 (truncate:DI
4577 (lshiftrt:TI (mult:TI (sign_extend:TI
4578 (match_operand:DI 1 "gpc_reg_operand" "%r"))
4579 (sign_extend:TI
4580 (match_operand:DI 2 "gpc_reg_operand" "r")))
4581 (const_int 64))))]
4582 "TARGET_POWERPC64"
4583 "mulhd %0,%1,%2"
4584 [(set_attr "type" "imul")])
4585
4586(define_insn "umuldi3_highpart"
4587 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4588 (truncate:DI
4589 (lshiftrt:TI (mult:TI (zero_extend:TI
4590 (match_operand:DI 1 "gpc_reg_operand" "%r"))
4591 (zero_extend:TI
4592 (match_operand:DI 2 "gpc_reg_operand" "r")))
4593 (const_int 64))))]
4594 "TARGET_POWERPC64"
4595 "mulhdu %0,%1,%2"
4596 [(set_attr "type" "imul")])
4597
4598(define_expand "divdi3"
4599 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4600 (div:DI (match_operand:DI 1 "gpc_reg_operand" "")
4601 (match_operand:DI 2 "reg_or_cint_operand" "")))]
4602 "TARGET_POWERPC64"
4603 "
4604{
4605 if (GET_CODE (operands[2]) == CONST_INT
4606 && exact_log2 (INTVAL (operands[2])) >= 0)
4607 ;
4608 else
4609 operands[2] = force_reg (DImode, operands[2]);
4610}")
4611
4612(define_expand "moddi3"
4613 [(use (match_operand:DI 0 "gpc_reg_operand" ""))
4614 (use (match_operand:DI 1 "gpc_reg_operand" ""))
4615 (use (match_operand:DI 2 "reg_or_cint_operand" ""))]
4616 "TARGET_POWERPC64"
4617 "
4618{
4619 int i = exact_log2 (INTVAL (operands[2]));
4620 rtx temp1;
4621 rtx temp2;
4622
4623 if (GET_CODE (operands[2]) != CONST_INT || i < 0)
4624 FAIL;
4625
4626 temp1 = gen_reg_rtx (DImode);
4627 temp2 = gen_reg_rtx (DImode);
4628
4629 emit_insn (gen_divdi3 (temp1, operands[1], operands[2]));
4630 emit_insn (gen_ashldi3 (temp2, temp1, GEN_INT (i)));
4631 emit_insn (gen_subdi3 (operands[0], operands[1], temp2));
4632 DONE;
4633}")
4634
4635(define_insn ""
4636 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4637 (div:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4638 (match_operand:DI 2 "const_int_operand" "N")))]
4639 "TARGET_POWERPC64 && exact_log2 (INTVAL (operands[2])) >= 0"
4640 "sradi %0,%1,%p2\;addze %0,%0"
4641 [(set_attr "length" "8")])
4642
4643(define_insn ""
4644 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4645 (compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4646 (match_operand:DI 2 "const_int_operand" "N"))
4647 (const_int 0)))
4648 (clobber (match_scratch:DI 3 "=r"))]
4649 "TARGET_POWERPC64 && exact_log2 (INTVAL (operands[2])) >= 0"
4650 "sradi %3,%1,%p2\;addze. %3,%3"
4651 [(set_attr "type" "compare")
4652 (set_attr "length" "8")])
4653
4654(define_insn ""
4655 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4656 (compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4657 (match_operand:DI 2 "const_int_operand" "N"))
4658 (const_int 0)))
4659 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4660 (div:DI (match_dup 1) (match_dup 2)))]
4661 "TARGET_POWERPC64 && exact_log2 (INTVAL (operands[2])) >= 0"
4662 "sradi %0,%1,%p2\;addze. %0,%0"
4663 [(set_attr "type" "compare")
4664 (set_attr "length" "8")])
4665
4666(define_insn ""
4667 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4668 (div:DI (match_operand:DI 1 "gpc_reg_operand" "r")
a260abc9 4669 (match_operand:DI 2 "gpc_reg_operand" "r")))]
266eb58a
DE
4670 "TARGET_POWERPC64"
4671 "divd %0,%1,%2"
4672 [(set_attr "type" "idiv")])
4673
4674(define_insn "udivdi3"
4675 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4676 (udiv:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4677 (match_operand:DI 2 "gpc_reg_operand" "r")))]
4678 "TARGET_POWERPC64"
4679 "divdu %0,%1,%2"
4680 [(set_attr "type" "idiv")])
4681
4682(define_insn "rotldi3"
4683 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4684 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4685 (match_operand:DI 2 "reg_or_cint_operand" "ri")))]
4686 "TARGET_POWERPC64"
a66078ee 4687 "rld%I2cl %0,%1,%H2,0")
266eb58a 4688
a260abc9 4689(define_insn "*rotldi3_internal2"
266eb58a
DE
4690 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4691 (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4692 (match_operand:DI 2 "reg_or_cint_operand" "ri"))
4693 (const_int 0)))
4694 (clobber (match_scratch:DI 3 "=r"))]
4695 "TARGET_POWERPC64"
a66078ee 4696 "rld%I2cl. %3,%1,%H2,0"
266eb58a
DE
4697 [(set_attr "type" "delayed_compare")])
4698
a260abc9 4699(define_insn "*rotldi3_internal3"
266eb58a
DE
4700 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4701 (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4702 (match_operand:DI 2 "reg_or_cint_operand" "ri"))
4703 (const_int 0)))
4704 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4705 (rotate:DI (match_dup 1) (match_dup 2)))]
4706 "TARGET_POWERPC64"
a66078ee 4707 "rld%I2cl. %0,%1,%H2,0"
266eb58a
DE
4708 [(set_attr "type" "delayed_compare")])
4709
a260abc9
DE
4710(define_insn "*rotldi3_internal4"
4711 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4712 (and:DI (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4713 (match_operand:DI 2 "reg_or_cint_operand" "ri"))
4714 (match_operand:DI 3 "mask64_operand" "S")))]
4715 "TARGET_POWERPC64"
4716 "rld%I2c%B3 %0,%1,%H2,%S3")
4717
4718(define_insn "*rotldi3_internal5"
4719 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4720 (compare:CC (and:DI
4721 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4722 (match_operand:DI 2 "reg_or_cint_operand" "ri"))
4723 (match_operand:DI 3 "mask64_operand" "S"))
4724 (const_int 0)))
4725 (clobber (match_scratch:DI 4 "=r"))]
4726 "TARGET_POWERPC64"
4727 "rld%I2c%B3. %4,%1,%H2,%S3"
4728 [(set_attr "type" "delayed_compare")])
4729
4730(define_insn "*rotldi3_internal6"
4731 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
4732 (compare:CC (and:DI
4733 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4734 (match_operand:DI 2 "reg_or_cint_operand" "ri"))
4735 (match_operand:DI 3 "mask64_operand" "S"))
4736 (const_int 0)))
4737 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4738 (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
4739 "TARGET_POWERPC64"
4740 "rld%I2c%B3. %0,%1,%H2,%S3"
4741 [(set_attr "type" "delayed_compare")])
4742
4743(define_insn "*rotldi3_internal7"
4744 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4745 (zero_extend:DI
4746 (subreg:QI
4747 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4748 (match_operand:DI 2 "reg_or_cint_operand" "ri")) 0)))]
4749 "TARGET_POWERPC64"
4750 "rld%I2cl %0,%1,%H2,56")
4751
4752(define_insn "*rotldi3_internal8"
4753 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4754 (compare:CC (zero_extend:DI
4755 (subreg:QI
4756 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4757 (match_operand:DI 2 "reg_or_cint_operand" "ri")) 0))
4758 (const_int 0)))
4759 (clobber (match_scratch:DI 3 "=r"))]
4760 "TARGET_POWERPC64"
4761 "rld%I2cl. %3,%1,%H2,56"
4762 [(set_attr "type" "delayed_compare")])
4763
4764(define_insn "*rotldi3_internal9"
4765 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4766 (compare:CC (zero_extend:DI
4767 (subreg:QI
4768 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4769 (match_operand:DI 2 "reg_or_cint_operand" "ri")) 0))
4770 (const_int 0)))
4771 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4772 (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
4773 "TARGET_POWERPC64"
4774 "rld%I2cl. %0,%1,%H2,56"
4775 [(set_attr "type" "delayed_compare")])
4776
4777(define_insn "*rotldi3_internal10"
4778 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4779 (zero_extend:DI
4780 (subreg:HI
4781 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4782 (match_operand:DI 2 "reg_or_cint_operand" "ri")) 0)))]
4783 "TARGET_POWERPC64"
4784 "rld%I2cl %0,%1,%H2,48")
4785
4786(define_insn "*rotldi3_internal11"
4787 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4788 (compare:CC (zero_extend:DI
4789 (subreg:HI
4790 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4791 (match_operand:DI 2 "reg_or_cint_operand" "ri")) 0))
4792 (const_int 0)))
4793 (clobber (match_scratch:DI 3 "=r"))]
4794 "TARGET_POWERPC64"
4795 "rld%I2cl. %3,%1,%H2,48"
4796 [(set_attr "type" "delayed_compare")])
4797
4798(define_insn "*rotldi3_internal12"
4799 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4800 (compare:CC (zero_extend:DI
4801 (subreg:HI
4802 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4803 (match_operand:DI 2 "reg_or_cint_operand" "ri")) 0))
4804 (const_int 0)))
4805 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4806 (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
4807 "TARGET_POWERPC64"
4808 "rld%I2cl. %0,%1,%H2,48"
4809 [(set_attr "type" "delayed_compare")])
4810
4811(define_insn "*rotldi3_internal13"
4812 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4813 (zero_extend:DI
4814 (subreg:SI
4815 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4816 (match_operand:DI 2 "reg_or_cint_operand" "ri")) 0)))]
4817 "TARGET_POWERPC64"
4818 "rld%I2cl %0,%1,%H2,32")
4819
4820(define_insn "*rotldi3_internal14"
4821 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4822 (compare:CC (zero_extend:DI
4823 (subreg:SI
4824 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4825 (match_operand:DI 2 "reg_or_cint_operand" "ri")) 0))
4826 (const_int 0)))
4827 (clobber (match_scratch:DI 3 "=r"))]
4828 "TARGET_POWERPC64"
4829 "rld%I2cl. %3,%1,%H2,32"
4830 [(set_attr "type" "delayed_compare")])
4831
4832(define_insn "*rotldi3_internal15"
4833 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4834 (compare:CC (zero_extend:DI
4835 (subreg:SI
4836 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4837 (match_operand:DI 2 "reg_or_cint_operand" "ri")) 0))
4838 (const_int 0)))
4839 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4840 (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
4841 "TARGET_POWERPC64"
4842 "rld%I2cl. %0,%1,%H2,32"
4843 [(set_attr "type" "delayed_compare")])
4844
266eb58a
DE
4845(define_expand "ashldi3"
4846 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4847 (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
4848 (match_operand:SI 2 "reg_or_cint_operand" "")))]
4849 "TARGET_POWERPC64 || TARGET_POWER"
4850 "
4851{
4852 if (TARGET_POWERPC64)
4853 ;
4854 else if (TARGET_POWER)
4855 {
4856 emit_insn (gen_ashldi3_power (operands[0], operands[1], operands[2]));
4857 DONE;
4858 }
4859 else
4860 FAIL;
4861}")
4862
4863(define_insn ""
4864 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4865 (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4866 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
4867 "TARGET_POWERPC64"
a66078ee 4868 "sld%I2 %0,%1,%H2"
266eb58a
DE
4869 [(set_attr "length" "8")])
4870
4871(define_insn ""
4872 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4873 (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4874 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
4875 (const_int 0)))
4876 (clobber (match_scratch:DI 3 "=r"))]
4877 "TARGET_POWERPC64"
a66078ee 4878 "sld%I2. %3,%1,%H2"
266eb58a
DE
4879 [(set_attr "type" "delayed_compare")])
4880
4881(define_insn ""
4882 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4883 (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4884 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
4885 (const_int 0)))
4886 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4887 (ashift:DI (match_dup 1) (match_dup 2)))]
4888 "TARGET_POWERPC64"
a66078ee 4889 "sld%I2. %0,%1,%H2"
266eb58a
DE
4890 [(set_attr "type" "delayed_compare")])
4891
4892(define_expand "lshrdi3"
4893 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4894 (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
4895 (match_operand:SI 2 "reg_or_cint_operand" "")))]
4896 "TARGET_POWERPC64 || TARGET_POWER"
4897 "
4898{
4899 if (TARGET_POWERPC64)
4900 ;
4901 else if (TARGET_POWER)
4902 {
4903 emit_insn (gen_lshrdi3_power (operands[0], operands[1], operands[2]));
4904 DONE;
4905 }
4906 else
4907 FAIL;
4908}")
4909
4910(define_insn ""
4911 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4912 (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4913 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
4914 "TARGET_POWERPC64"
a66078ee 4915 "srd%I2 %0,%1,%H2")
266eb58a
DE
4916
4917(define_insn ""
4918 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4919 (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4920 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
4921 (const_int 0)))
4922 (clobber (match_scratch:DI 3 "=r"))]
4923 "TARGET_POWERPC64"
a66078ee 4924 "srd%I2. %3,%1,%H2"
266eb58a
DE
4925 [(set_attr "type" "delayed_compare")])
4926
4927(define_insn ""
4928 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4929 (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4930 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
4931 (const_int 0)))
4932 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4933 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
4934 "TARGET_POWERPC64"
a66078ee 4935 "srd%I2. %0,%1,%H2"
266eb58a
DE
4936 [(set_attr "type" "delayed_compare")])
4937
4938(define_expand "ashrdi3"
4939 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4940 (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
4941 (match_operand:SI 2 "reg_or_cint_operand" "")))]
4942 "TARGET_POWERPC64 || TARGET_POWER"
4943 "
4944{
4945 if (TARGET_POWERPC64)
4946 ;
4947 else if (TARGET_POWER && GET_CODE (operands[2]) == CONST_INT)
4948 {
4949 emit_insn (gen_ashrdi3_power (operands[0], operands[1], operands[2]));
4950 DONE;
4951 }
4952 else
4953 FAIL;
4954}")
4955
4956(define_insn ""
4957 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4958 (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4959 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
4960 "TARGET_POWERPC64"
375490e0 4961 "srad%I2 %0,%1,%H2")
266eb58a
DE
4962
4963(define_insn ""
4964 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4965 (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4966 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
4967 (const_int 0)))
4968 (clobber (match_scratch:DI 3 "=r"))]
4969 "TARGET_POWERPC64"
375490e0 4970 "srad%I2. %3,%1,%H2"
266eb58a
DE
4971 [(set_attr "type" "delayed_compare")])
4972
4973(define_insn ""
4974 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4975 (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4976 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
4977 (const_int 0)))
4978 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4979 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
4980 "TARGET_POWERPC64"
375490e0 4981 "srad%I2. %0,%1,%H2"
266eb58a
DE
4982 [(set_attr "type" "delayed_compare")])
4983
4984(define_insn "anddi3"
a260abc9
DE
4985 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4986 (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r")
4987 (match_operand:DI 2 "and64_operand" "?r,S,K,J")))
4988 (clobber (match_scratch:CC 3 "=X,X,x,x"))]
266eb58a
DE
4989 "TARGET_POWERPC64"
4990 "@
4991 and %0,%1,%2
a260abc9 4992 rldic%B2 %0,%1,0,%S2
266eb58a
DE
4993 andi. %0,%1,%b2
4994 andis. %0,%1,%u2")
4995
a260abc9
DE
4996(define_insn "*anddi3_internal2"
4997 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x")
4998 (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r")
4999 (match_operand:DI 2 "and64_operand" "r,K,J,S"))
266eb58a 5000 (const_int 0)))
a260abc9 5001 (clobber (match_scratch:DI 3 "=r,r,r,r"))]
266eb58a
DE
5002 "TARGET_POWERPC64"
5003 "@
5004 and. %3,%1,%2
5005 andi. %3,%1,%b2
a260abc9
DE
5006 andis. %3,%1,%u2
5007 rldic%B2. %3,%1,0,%S2"
5008 [(set_attr "type" "compare,compare,compare,delayed_compare")])
266eb58a 5009
a260abc9
DE
5010(define_insn "*anddi3_internal3"
5011 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x")
5012 (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r")
5013 (match_operand:DI 2 "and64_operand" "r,K,J,S"))
266eb58a 5014 (const_int 0)))
a260abc9 5015 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
266eb58a
DE
5016 (and:DI (match_dup 1) (match_dup 2)))]
5017 "TARGET_POWERPC64"
5018 "@
5019 and. %0,%1,%2
5020 andi. %0,%1,%b2
a260abc9
DE
5021 andis. %0,%1,%u2
5022 rldic%B2. %3,%1,0,%S2"
5023 [(set_attr "type" "compare,compare,compare,delayed_compare")])
266eb58a 5024
a260abc9 5025(define_expand "iordi3"
266eb58a 5026 [(set (match_operand:DI 0 "gpc_reg_operand" "")
a260abc9
DE
5027 (ior:DI (match_operand:DI 1 "gpc_reg_operand" "")
5028 (match_operand:DI 2 "reg_or_cint_operand" "")))]
266eb58a 5029 "TARGET_POWERPC64"
266eb58a
DE
5030 "
5031{
a260abc9
DE
5032 if (GET_CODE (operands[2]) == CONST_INT
5033 && !logical_operand (operands[2], DImode))
266eb58a 5034 {
a260abc9
DE
5035 HOST_WIDE_INT value = INTVAL (operands[2]);
5036 rtx tmp = ((reload_in_progress || reload_completed
5037 || rtx_equal_p (operands[0], operands[1]))
5038 ? operands[0] : gen_reg_rtx (DImode));
266eb58a 5039
a260abc9
DE
5040 emit_insn (gen_iordi3 (tmp, operands[1],
5041 GEN_INT (value & (~ (HOST_WIDE_INT) 0xffff))));
5042 emit_insn (gen_iordi3 (operands[0], tmp, GEN_INT (value & 0xffff)));
5043 DONE;
266eb58a 5044 }
266eb58a
DE
5045}")
5046
a260abc9 5047(define_insn "*iordi3_internal1"
266eb58a
DE
5048 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
5049 (ior:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r")
5050 (match_operand:DI 2 "logical_operand" "r,K,J")))]
5051 "TARGET_POWERPC64"
5052 "@
5053 or %0,%1,%2
5054 ori %0,%1,%b2
5055 oris %0,%1,%u2")
5056
a260abc9 5057(define_insn "*iordi3_internal2"
266eb58a
DE
5058 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
5059 (compare:CC (ior:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
5060 (match_operand:DI 2 "gpc_reg_operand" "r"))
5061 (const_int 0)))
5062 (clobber (match_scratch:DI 3 "=r"))]
5063 "TARGET_POWERPC64"
5064 "or. %3,%1,%2"
5065 [(set_attr "type" "compare")])
5066
a260abc9 5067(define_insn "*iordi3_internal3"
266eb58a
DE
5068 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
5069 (compare:CC (ior:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
5070 (match_operand:DI 2 "gpc_reg_operand" "r"))
5071 (const_int 0)))
5072 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
5073 (ior:DI (match_dup 1) (match_dup 2)))]
5074 "TARGET_POWERPC64"
5075 "or. %0,%1,%2"
5076 [(set_attr "type" "compare")])
5077
5078;; Split an IOR that we can't do in one insn into two insns, each of which
5079;; does one 16-bit part. This is used by combine.
5080
5081(define_split
5082 [(set (match_operand:DI 0 "gpc_reg_operand" "")
5083 (ior:DI (match_operand:DI 1 "gpc_reg_operand" "")
5084 (match_operand:DI 2 "non_logical_cint_operand" "")))]
5085 "TARGET_POWERPC64"
5086 [(set (match_dup 0) (ior:DI (match_dup 1) (match_dup 3)))
5087 (set (match_dup 0) (ior:DI (match_dup 0) (match_dup 4)))]
5088"
5089{
3a598fbe 5090 operands[3] = GEN_INT (INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff));
89e9f3a8 5091 operands[4] = GEN_INT (INTVAL (operands[2]) & 0xffff);
266eb58a 5092}")
1fd4e8c1 5093
a260abc9
DE
5094(define_expand "xordi3"
5095 [(set (match_operand:DI 0 "gpc_reg_operand" "")
5096 (xor:DI (match_operand:DI 1 "gpc_reg_operand" "")
5097 (match_operand:DI 2 "reg_or_cint_operand" "")))]
5098 "TARGET_POWERPC64"
5099 "
5100{
5101 if (GET_CODE (operands[2]) == CONST_INT
5102 && !logical_operand (operands[2], DImode))
5103 {
5104 HOST_WIDE_INT value = INTVAL (operands[2]);
5105 rtx tmp = ((reload_in_progress || reload_completed
5106 || rtx_equal_p (operands[0], operands[1]))
5107 ? operands[0] : gen_reg_rtx (DImode));
5108
5109 emit_insn (gen_xordi3 (tmp, operands[1],
5110 GEN_INT (value & (~ (HOST_WIDE_INT) 0xffff))));
5111 emit_insn (gen_xordi3 (operands[0], tmp, GEN_INT (value & 0xffff)));
5112 DONE;
5113 }
5114}")
5115
5116(define_insn "*xordi3_internal1"
266eb58a
DE
5117 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
5118 (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r")
5119 (match_operand:DI 2 "logical_operand" "r,K,J")))]
5120 "TARGET_POWERPC64"
1fd4e8c1 5121 "@
266eb58a
DE
5122 xor %0,%1,%2
5123 xori %0,%1,%b2
5124 xoris %0,%1,%u2")
1fd4e8c1 5125
a260abc9 5126(define_insn "*xordi3_internal2"
266eb58a
DE
5127 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
5128 (compare:CC (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
5129 (match_operand:DI 2 "gpc_reg_operand" "r"))
5130 (const_int 0)))
5131 (clobber (match_scratch:DI 3 "=r"))]
5132 "TARGET_POWERPC64"
5133 "xor. %3,%1,%2"
5134 [(set_attr "type" "compare")])
1fd4e8c1 5135
a260abc9 5136(define_insn "*xordi3_internal3"
266eb58a
DE
5137 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
5138 (compare:CC (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
5139 (match_operand:DI 2 "gpc_reg_operand" "r"))
5140 (const_int 0)))
5141 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
5142 (xor:DI (match_dup 1) (match_dup 2)))]
5143 "TARGET_POWERPC64"
5144 "xor. %0,%1,%2"
5145 [(set_attr "type" "compare")])
1fd4e8c1 5146
266eb58a
DE
5147;; Split an XOR that we can't do in one insn into two insns, each of which
5148;; does one 16-bit part. This is used by combine.
5149
5150(define_split
5151 [(set (match_operand:DI 0 "gpc_reg_operand" "")
a260abc9
DE
5152 (xor:DI (match_operand:DI 1 "gpc_reg_operand" "")
5153 (match_operand:DI 2 "non_logical_cint_operand" "")))]
266eb58a
DE
5154 "TARGET_POWERPC64"
5155 [(set (match_dup 0) (xor:DI (match_dup 1) (match_dup 3)))
5156 (set (match_dup 0) (xor:DI (match_dup 0) (match_dup 4)))]
5157"
5158{
a260abc9 5159 operands[3] = GEN_INT (INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff));
89e9f3a8 5160 operands[4] = GEN_INT (INTVAL (operands[2]) & 0xffff);
1fd4e8c1
RK
5161}")
5162
a260abc9 5163(define_insn "*eqvdi3_internal1"
266eb58a
DE
5164 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
5165 (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
5166 (match_operand:DI 2 "gpc_reg_operand" "r"))))]
5167 "TARGET_POWERPC64"
5168 "eqv %0,%1,%2")
a473029f 5169
a260abc9 5170(define_insn "*eqvdi3_internal2"
266eb58a
DE
5171 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
5172 (compare:CC (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
5173 (match_operand:DI 2 "gpc_reg_operand" "r")))
5174 (const_int 0)))
5175 (clobber (match_scratch:DI 3 "=r"))]
5176 "TARGET_POWERPC64"
5177 "eqv. %3,%1,%2"
5178 [(set_attr "type" "compare")])
a473029f 5179
a260abc9 5180(define_insn "*eqvdi3_internal3"
266eb58a
DE
5181 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
5182 (compare:CC (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
5183 (match_operand:DI 2 "gpc_reg_operand" "r")))
5184 (const_int 0)))
5185 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
5186 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5187 "TARGET_POWERPC64"
5188 "eqv. %0,%1,%2"
5189 [(set_attr "type" "compare")])
5190
a260abc9 5191(define_insn "*andcdi3_internal1"
a473029f 5192 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
266eb58a
DE
5193 (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
5194 (match_operand:DI 2 "gpc_reg_operand" "r")))]
a473029f 5195 "TARGET_POWERPC64"
266eb58a 5196 "andc %0,%2,%1")
a473029f 5197
a260abc9 5198(define_insn "*andcdi3_internal2"
266eb58a
DE
5199 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
5200 (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
5201 (match_operand:DI 2 "gpc_reg_operand" "r"))
5202 (const_int 0)))
5203 (clobber (match_scratch:DI 3 "=r"))]
a473029f 5204 "TARGET_POWERPC64"
266eb58a
DE
5205 "andc. %3,%2,%1"
5206 [(set_attr "type" "compare")])
a473029f 5207
a260abc9 5208(define_insn "*andcdi3_internal3"
266eb58a
DE
5209 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
5210 (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
5211 (match_operand:DI 2 "gpc_reg_operand" "r"))
5212 (const_int 0)))
5213 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
5214 (and:DI (not:DI (match_dup 1)) (match_dup 2)))]
a473029f 5215 "TARGET_POWERPC64"
266eb58a
DE
5216 "andc. %0,%2,%1"
5217 [(set_attr "type" "compare")])
a473029f 5218
a260abc9 5219(define_insn "*iorcdi3_internal1"
a473029f 5220 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
266eb58a
DE
5221 (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
5222 (match_operand:DI 2 "gpc_reg_operand" "r")))]
a473029f 5223 "TARGET_POWERPC64"
266eb58a 5224 "orc %0,%2,%1")
a473029f 5225
a260abc9 5226(define_insn "*iorcdi3_inernal2"
266eb58a
DE
5227 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
5228 (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
5229 (match_operand:DI 2 "gpc_reg_operand" "r"))
5230 (const_int 0)))
5231 (clobber (match_scratch:DI 3 "=r"))]
5232 "TARGET_POWERPC64"
5233 "orc. %3,%2,%1"
5234 [(set_attr "type" "compare")])
5235
a260abc9 5236(define_insn "*iorcdi3_internal3"
266eb58a
DE
5237 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
5238 (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
5239 (match_operand:DI 2 "gpc_reg_operand" "r"))
5240 (const_int 0)))
5241 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
5242 (ior:DI (not:DI (match_dup 1)) (match_dup 2)))]
5243 "TARGET_POWERPC64"
5244 "orc. %0,%2,%1"
5245 [(set_attr "type" "compare")])
5246
a260abc9 5247(define_insn "*nanddi3_internal1"
a473029f 5248 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
266eb58a
DE
5249 (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
5250 (not:DI (match_operand:DI 2 "gpc_reg_operand" "r"))))]
a473029f 5251 "TARGET_POWERPC64"
266eb58a 5252 "nand %0,%1,%2")
a473029f 5253
a260abc9 5254(define_insn "*nanddi3_internal2"
266eb58a
DE
5255 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
5256 (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
5257 (not:DI (match_operand:DI 2 "gpc_reg_operand" "r")))
5258 (const_int 0)))
5259 (clobber (match_scratch:DI 3 "=r"))]
5260 "TARGET_POWERPC64"
5261 "nand. %3,%1,%2"
5262 [(set_attr "type" "compare")])
5263
a260abc9 5264(define_insn "*nanddi3_internal3"
266eb58a
DE
5265 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
5266 (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
5267 (not:DI (match_operand:DI 2 "gpc_reg_operand" "r")))
5268 (const_int 0)))
5269 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
5270 (ior:DI (not:DI (match_dup 1)) (not:DI (match_dup 2))))]
5271 "TARGET_POWERPC64"
5272 "nand. %0,%1,%2"
5273 [(set_attr "type" "compare")])
5274
a260abc9 5275(define_insn "*nordi3_internal1"
a473029f 5276 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
266eb58a
DE
5277 (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
5278 (not:DI (match_operand:DI 2 "gpc_reg_operand" "r"))))]
a473029f 5279 "TARGET_POWERPC64"
266eb58a 5280 "nor %0,%1,%2")
a473029f 5281
a260abc9 5282(define_insn "*nordi3_internal2"
a473029f 5283 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
266eb58a
DE
5284 (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
5285 (not:DI (match_operand:DI 2 "gpc_reg_operand" "r")))
a473029f
RK
5286 (const_int 0)))
5287 (clobber (match_scratch:DI 3 "=r"))]
5288 "TARGET_POWERPC64"
266eb58a
DE
5289 "nor. %3,%1,%2"
5290 [(set_attr "type" "compare")])
a473029f 5291
a260abc9 5292(define_insn "*nordi3_internal3"
a473029f 5293 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
266eb58a
DE
5294 (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
5295 (not:DI (match_operand:DI 2 "gpc_reg_operand" "r")))
a473029f
RK
5296 (const_int 0)))
5297 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
266eb58a 5298 (and:DI (not:DI (match_dup 1)) (not:DI (match_dup 2))))]
a473029f 5299 "TARGET_POWERPC64"
266eb58a
DE
5300 "nor. %0,%1,%2"
5301 [(set_attr "type" "compare")])
a473029f 5302\f
1fd4e8c1 5303;; Now define ways of moving data around.
4697a36c
MM
5304
5305;; Elf specific ways of loading addresses for non-PIC code.
5306;; The output of this could be r0, but we limit it to base
5307;; registers, since almost all uses of this will need it
5308;; in a base register shortly.
5309(define_insn "elf_high"
5310 [(set (match_operand:SI 0 "register_operand" "=b")
5311 (high:SI (match_operand 1 "" "")))]
5312 "TARGET_ELF && !TARGET_64BIT"
5313 "{cau|addis} %0,0,%1@ha")
5314
5315(define_insn "elf_low"
5316 [(set (match_operand:SI 0 "register_operand" "=r")
5317 (lo_sum:SI (match_operand:SI 1 "register_operand" "b")
5318 (match_operand 2 "" "")))]
5319 "TARGET_ELF && !TARGET_64BIT"
5320 "{cal %0,%a2@l(%1)|addi %0,%1,%2@l}")
5321
766a866c
MM
5322;; Set up a register with a value from the GOT table
5323
5324(define_expand "movsi_got"
5325 [(set (match_operand:SI 0 "register_operand" "")
5326 (unspec [(match_operand:SI 1 "got_operand" "")
5327 (match_dup 2)] 8))]
58307bcd 5328 "(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) && flag_pic == 1"
766a866c
MM
5329 "
5330{
38c1f2d7
MM
5331 if (GET_CODE (operands[1]) == CONST)
5332 {
5333 rtx offset = const0_rtx;
5334 HOST_WIDE_INT value;
5335
5336 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
5337 value = INTVAL (offset);
5338 if (value != 0)
5339 {
5340 rtx tmp = ((reload_in_progress || reload_completed)
5341 ? operands[0]
5342 : gen_reg_rtx (Pmode));
5343 emit_insn (gen_movsi_got (tmp, operands[1]));
5344 emit_insn (gen_addsi3 (operands[0], tmp, offset));
5345 DONE;
5346 }
5347 }
5348
c4c40373 5349 operands[2] = rs6000_got_register (operands[1]);
766a866c
MM
5350}")
5351
84f414bc 5352(define_insn "*movsi_got_internal"
766a866c 5353 [(set (match_operand:SI 0 "register_operand" "=r")
38c1f2d7 5354 (unspec [(match_operand:SI 1 "got_no_const_operand" "")
766a866c 5355 (match_operand:SI 2 "register_operand" "b")] 8))]
c81bebd7 5356 "(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) && flag_pic == 1"
766a866c
MM
5357 "{l|lwz} %0,%a1@got(%2)"
5358 [(set_attr "type" "load")])
5359
b22b9b3e
JL
5360;; Sometimes, though, the GOT `register' will be on the stack. Deal with
5361;; this case specially.
5362;; Force final to split this insn (if it hasn't been split already) to
5363;; avoid having to create a suitable output template.
5364(define_insn "*movsi_got_internal_mem"
5365 [(set (match_operand:SI 0 "register_operand" "=r")
5366 (unspec [(match_operand:SI 1 "got_no_const_operand" "")
5367 (match_operand:SI 2 "memory_operand" "m")] 8))]
5368 "(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
5369 && flag_pic == 1
5370 && (reload_in_progress || reload_completed)"
5371 "#"
5372 [(set_attr "type" "load")
5373 (set_attr "length" "8")])
5374
5375;; Used by sched, shorten_branches and final when the GOT pseudo reg
5376;; didn't get allocated to a hard register.
5377(define_split
5378 [(set (match_operand:SI 0 "register_operand" "=r")
5379 (unspec [(match_operand:SI 1 "got_no_const_operand" "")
5380 (match_operand:SI 2 "memory_operand" "m")] 8))]
5381 "(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
5382 && flag_pic == 1
5383 && (reload_in_progress || reload_completed)"
5384 [(set (match_dup 0) (match_dup 2))
5385 (set (match_dup 0) (unspec [(match_dup 1)(match_dup 0)] 8))]
5386 "")
5387
1fd4e8c1
RK
5388;; For SI, we special-case integers that can't be loaded in one insn. We
5389;; do the load 16-bits at a time. We could do this by loading from memory,
5390;; and this is even supposed to be faster, but it is simpler not to get
5391;; integers in the TOC.
5392(define_expand "movsi"
5393 [(set (match_operand:SI 0 "general_operand" "")
5394 (match_operand:SI 1 "any_operand" ""))]
5395 ""
5396 "
5397{
5398 if (GET_CODE (operands[0]) != REG)
5399 operands[1] = force_reg (SImode, operands[1]);
5400
ef0e171b
RK
5401 /* Convert a move of a CONST_DOUBLE into a CONST_INT */
5402 if (GET_CODE (operands[1]) == CONST_DOUBLE)
5403 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
5404
88228c4b
MM
5405 /* Use default pattern for address of ELF small data */
5406 if (TARGET_ELF
c81bebd7 5407 && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
88228c4b 5408 && (GET_CODE (operands[1]) == SYMBOL_REF || GET_CODE (operands[1]) == CONST)
e98bb982 5409 && small_data_operand (operands[1], SImode))
88228c4b
MM
5410 {
5411 emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
5412 DONE;
5413 }
5414
c81bebd7 5415 if ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
84f414bc 5416 && flag_pic == 1 && got_operand (operands[1], SImode))
766a866c
MM
5417 {
5418 emit_insn (gen_movsi_got (operands[0], operands[1]));
5419 DONE;
5420 }
5421
4697a36c 5422 if (TARGET_ELF && TARGET_NO_TOC && !TARGET_64BIT
461422d5 5423 && !flag_pic
4697a36c
MM
5424 && CONSTANT_P (operands[1])
5425 && GET_CODE (operands[1]) != HIGH
5426 && GET_CODE (operands[1]) != CONST_INT)
5427 {
5428 rtx target = (reload_completed || reload_in_progress)
5429 ? operands[0] : gen_reg_rtx (SImode);
5430
b6c9286a
MM
5431 /* If this is a function address on -mcall-aixdesc or -mcall-nt,
5432 convert it to the address of the descriptor. */
5433 if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
5434 && GET_CODE (operands[1]) == SYMBOL_REF
5435 && XSTR (operands[1], 0)[0] == '.')
5436 {
5437 char *name = XSTR (operands[1], 0);
5438 rtx new_ref;
5439 while (*name == '.')
5440 name++;
5441 new_ref = gen_rtx (SYMBOL_REF, Pmode, name);
5442 CONSTANT_POOL_ADDRESS_P (new_ref) = CONSTANT_POOL_ADDRESS_P (operands[1]);
5443 SYMBOL_REF_FLAG (new_ref) = SYMBOL_REF_FLAG (operands[1]);
5444 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
5445 operands[1] = new_ref;
5446 }
5447
4697a36c
MM
5448 emit_insn (gen_elf_high (target, operands[1]));
5449 emit_insn (gen_elf_low (operands[0], target, operands[1]));
5450 DONE;
5451 }
5452
b6c9286a
MM
5453 if (GET_CODE (operands[1]) == CONST
5454 && DEFAULT_ABI == ABI_NT
5455 && !side_effects_p (operands[0]))
5456 {
5457 rtx const_term = const0_rtx;
5458 rtx sym = eliminate_constant_term (XEXP (operands[1], 0), &const_term);
5459 if (sym && GET_CODE (const_term) == CONST_INT
5460 && (GET_CODE (sym) == SYMBOL_REF || GET_CODE (sym) == LABEL_REF))
5461 {
354b734b
MM
5462 unsigned HOST_WIDE_INT value = INTVAL (const_term);
5463 int new_reg_p = (flag_expensive_optimizations
5464 && !reload_completed
5465 && !reload_in_progress);
5466 rtx tmp1 = (new_reg_p && value != 0) ? gen_reg_rtx (SImode) : operands[0];
5467
5468 emit_insn (gen_movsi (tmp1, sym));
b6c9286a 5469 if (INTVAL (const_term) != 0)
38c1f2d7 5470 emit_insn (gen_addsi3 (operands[0], tmp1, GEN_INT (value)));
b6c9286a
MM
5471 DONE;
5472 }
5473 else
5474 fatal_insn (\"bad address\", operands[1]);
5475 }
5476
5477 if ((!TARGET_WINDOWS_NT || DEFAULT_ABI != ABI_NT)
5478 && CONSTANT_P (operands[1])
4697a36c
MM
5479 && GET_CODE (operands[1]) != CONST_INT
5480 && GET_CODE (operands[1]) != HIGH
78b8d850 5481 && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1]))
b45863ec 5482 {
d302f4f2
MM
5483 /* Emit a USE operation so that the constant isn't deleted if
5484 expensive optimizations are turned on because nobody
e0350319
MM
5485 references it. This should only be done for operands that
5486 contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set.
5487 This should not be done for operands that contain LABEL_REFs.
5488 For now, we just handle the obvious case. */
5489 if (GET_CODE (operands[1]) != LABEL_REF)
5490 emit_insn (gen_rtx (USE, VOIDmode, operands[1]));
d302f4f2 5491
30a4619d
RK
5492 /* If we are to limit the number of things we put in the TOC and
5493 this is a symbol plus a constant we can add in one insn,
abc95ed3 5494 just put the symbol in the TOC and add the constant. Don't do
30a4619d
RK
5495 this if reload is in progress. */
5496 if (GET_CODE (operands[1]) == CONST
5497 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
5498 && GET_CODE (XEXP (operands[1], 0)) == PLUS
5499 && add_operand (XEXP (XEXP (operands[1], 0), 1), SImode)
5500 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
5501 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
5502 && ! side_effects_p (operands[0]))
5503 {
5504 rtx sym = force_const_mem (SImode, XEXP (XEXP (operands[1], 0), 0));
5505 rtx other = XEXP (XEXP (operands[1], 0), 1);
5506
5507 emit_insn (gen_addsi3 (operands[0], force_reg (SImode, sym), other));
5508 DONE;
5509 }
5510
b45863ec
RK
5511 operands[1] = force_const_mem (SImode, operands[1]);
5512 if (! memory_address_p (SImode, XEXP (operands[1], 0))
5513 && ! reload_in_progress)
5514 operands[1] = change_address (operands[1], SImode,
5515 XEXP (operands[1], 0));
5516 }
1fd4e8c1
RK
5517}")
5518
5519(define_insn ""
a260abc9
DE
5520 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,r,r,r,r,r,*q,*c*l,*h")
5521 (match_operand:SI 1 "input_operand" "r,U,m,r,I,J,n,R,*h,r,r,0"))]
19d5775a
RK
5522 "gpc_reg_operand (operands[0], SImode)
5523 || gpc_reg_operand (operands[1], SImode)"
1fd4e8c1 5524 "@
deb9225a 5525 mr %0,%1
b9442c72 5526 {cal|la} %0,%a1
ca7f5001
RK
5527 {l%U1%X1|lwz%U1%X1} %0,%1
5528 {st%U0%X0|stw%U0%X0} %1,%0
19d5775a 5529 {lil|li} %0,%1
802a0058 5530 {liu|lis} %0,%v1
beaec479 5531 #
57fa6739 5532 {cal|la} %0,%1(%*)
1fd4e8c1 5533 mf%1 %0
5c23c401 5534 mt%0 %1
e76e75bb
RK
5535 mt%0 %1
5536 cror 0,0,0"
a260abc9
DE
5537 [(set_attr "type" "*,*,load,store,*,*,*,*,*,*,mtjmpr,*")
5538 (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4")])
1fd4e8c1 5539
77fa0940
RK
5540;; Split a load of a large constant into the appropriate two-insn
5541;; sequence.
5542
5543(define_split
5544 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5545 (match_operand:SI 1 "const_int_operand" ""))]
bb21487f 5546 "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
77fa0940
RK
5547 && (INTVAL (operands[1]) & 0xffff) != 0"
5548 [(set (match_dup 0)
5549 (match_dup 2))
5550 (set (match_dup 0)
5551 (ior:SI (match_dup 0)
5552 (match_dup 3)))]
5553 "
5554{
3a598fbe 5555 operands[2] = GEN_INT (INTVAL (operands[1]) & 0xffff0000);
89e9f3a8 5556 operands[3] = GEN_INT (INTVAL (operands[1]) & 0xffff);
77fa0940
RK
5557}")
5558
1fd4e8c1
RK
5559(define_insn ""
5560 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
cd2b37d9 5561 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 5562 (const_int 0)))
cd2b37d9 5563 (set (match_operand:SI 0 "gpc_reg_operand" "=r") (match_dup 1))]
1fd4e8c1 5564 ""
deb9225a 5565 "mr. %0,%1"
1fd4e8c1
RK
5566 [(set_attr "type" "compare")])
5567\f
5568(define_expand "movhi"
5569 [(set (match_operand:HI 0 "general_operand" "")
5570 (match_operand:HI 1 "any_operand" ""))]
5571 ""
5572 "
5573{
5574 if (GET_CODE (operands[0]) != REG)
5575 operands[1] = force_reg (HImode, operands[1]);
5576
5577 if (CONSTANT_P (operands[1]) && GET_CODE (operands[1]) != CONST_INT)
b45863ec
RK
5578 {
5579 operands[1] = force_const_mem (HImode, operands[1]);
5580 if (! memory_address_p (HImode, XEXP (operands[1], 0))
5581 && ! reload_in_progress)
5582 operands[1] = change_address (operands[1], HImode,
5583 XEXP (operands[1], 0));
5584 }
1fd4e8c1
RK
5585}")
5586
5587(define_insn ""
fb81d7ce
RK
5588 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*q,*c*l,*h")
5589 (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,r,0"))]
19d5775a
RK
5590 "gpc_reg_operand (operands[0], HImode)
5591 || gpc_reg_operand (operands[1], HImode)"
1fd4e8c1 5592 "@
deb9225a 5593 mr %0,%1
1fd4e8c1
RK
5594 lhz%U1%X1 %0,%1
5595 sth%U0%X0 %1,%0
19d5775a 5596 {lil|li} %0,%w1
1fd4e8c1 5597 mf%1 %0
e76e75bb 5598 mt%0 %1
fb81d7ce 5599 mt%0 %1
e76e75bb 5600 cror 0,0,0"
b7ff3d82 5601 [(set_attr "type" "*,load,store,*,*,*,mtjmpr,*")])
1fd4e8c1
RK
5602
5603(define_expand "movqi"
5604 [(set (match_operand:QI 0 "general_operand" "")
5605 (match_operand:QI 1 "any_operand" ""))]
5606 ""
5607 "
5608{
5609 if (GET_CODE (operands[0]) != REG)
5610 operands[1] = force_reg (QImode, operands[1]);
5611
5612 if (CONSTANT_P (operands[1]) && GET_CODE (operands[1]) != CONST_INT)
b45863ec
RK
5613 {
5614 operands[1] = force_const_mem (QImode, operands[1]);
5615 if (! memory_address_p (QImode, XEXP (operands[1], 0))
5616 && ! reload_in_progress)
5617 operands[1] = change_address (operands[1], QImode,
5618 XEXP (operands[1], 0));
5619 }
1fd4e8c1
RK
5620}")
5621
5622(define_insn ""
fb81d7ce
RK
5623 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*q,*c*l,*h")
5624 (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,r,0"))]
19d5775a
RK
5625 "gpc_reg_operand (operands[0], QImode)
5626 || gpc_reg_operand (operands[1], QImode)"
1fd4e8c1 5627 "@
deb9225a 5628 mr %0,%1
1fd4e8c1
RK
5629 lbz%U1%X1 %0,%1
5630 stb%U0%X0 %1,%0
19d5775a 5631 {lil|li} %0,%1
1fd4e8c1 5632 mf%1 %0
e76e75bb 5633 mt%0 %1
fb81d7ce 5634 mt%0 %1
e76e75bb 5635 cror 0,0,0"
b7ff3d82 5636 [(set_attr "type" "*,load,store,*,*,*,mtjmpr,*")])
1fd4e8c1
RK
5637\f
5638;; Here is how to move condition codes around. When we store CC data in
5639;; an integer register or memory, we store just the high-order 4 bits.
5640;; This lets us not shift in the most common case of CR0.
5641(define_expand "movcc"
5642 [(set (match_operand:CC 0 "nonimmediate_operand" "")
5643 (match_operand:CC 1 "nonimmediate_operand" ""))]
5644 ""
5645 "")
5646
5647(define_insn ""
5648 [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,y,r,r,r,r,m")
5649 (match_operand:CC 1 "nonimmediate_operand" "y,r,r,x,y,r,m,r"))]
5650 "register_operand (operands[0], CCmode)
5651 || register_operand (operands[1], CCmode)"
5652 "@
5653 mcrf %0,%1
5654 mtcrf 128,%1
ca7f5001 5655 {rlinm|rlwinm} %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;{rlinm|rlwinm} %1,%1,%f0,0xffffffff
1fd4e8c1 5656 mfcr %0
ca7f5001 5657 mfcr %0\;{rlinm|rlwinm} %0,%0,%f1,0xf0000000
deb9225a 5658 mr %0,%1
ca7f5001
RK
5659 {l%U1%X1|lwz%U1%X1} %0,%1
5660 {st%U0%U1|stw%U0%U1} %1,%0"
b7ff3d82 5661 [(set_attr "type" "*,*,*,compare,*,*,load,store")
b19003d8 5662 (set_attr "length" "*,*,12,*,8,*,*,*")])
1fd4e8c1 5663\f
e52e05ca
MM
5664;; For floating-point, we normally deal with the floating-point registers
5665;; unless -msoft-float is used. The sole exception is that parameter passing
5666;; can produce floating-point values in fixed-point registers. Unless the
5667;; value is a simple constant or already in memory, we deal with this by
5668;; allocating memory and copying the value explicitly via that memory location.
1fd4e8c1
RK
5669(define_expand "movsf"
5670 [(set (match_operand:SF 0 "nonimmediate_operand" "")
5671 (match_operand:SF 1 "any_operand" ""))]
5672 ""
5673 "
5674{
5675 /* If we are called from reload, we might be getting a SUBREG of a hard
5676 reg. So expand it. */
5677 if (GET_CODE (operands[0]) == SUBREG
5678 && GET_CODE (SUBREG_REG (operands[0])) == REG
5679 && REGNO (SUBREG_REG (operands[0])) < FIRST_PSEUDO_REGISTER)
5680 operands[0] = alter_subreg (operands[0]);
5681 if (GET_CODE (operands[1]) == SUBREG
5682 && GET_CODE (SUBREG_REG (operands[1])) == REG
5683 && REGNO (SUBREG_REG (operands[1])) < FIRST_PSEUDO_REGISTER)
5684 operands[1] = alter_subreg (operands[1]);
5685
3b7f6cca
MM
5686 if (TARGET_SOFT_FLOAT && GET_CODE (operands[0]) == MEM)
5687 operands[1] = force_reg (SFmode, operands[1]);
5688
5689 else if (TARGET_HARD_FLOAT)
1fd4e8c1 5690 {
e52e05ca 5691 if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 32)
1fd4e8c1 5692 {
e52e05ca
MM
5693 /* If this is a store to memory or another integer register do the
5694 move directly. Otherwise store to a temporary stack slot and
5695 load from there into a floating point register. */
5696
5697 if (GET_CODE (operands[0]) == MEM
5698 || (GET_CODE (operands[0]) == REG
5699 && (REGNO (operands[0]) < 32
5700 || (reload_in_progress
5701 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))))
5702 {
5703 emit_move_insn (operand_subword (operands[0], 0, 0, SFmode),
5704 operand_subword (operands[1], 0, 0, SFmode));
5705 DONE;
5706 }
5707 else
5708 {
5709 rtx stack_slot = assign_stack_temp (SFmode, 4, 0);
5710
5711 emit_move_insn (stack_slot, operands[1]);
5712 emit_move_insn (operands[0], stack_slot);
5713 DONE;
5714 }
f6ba0600 5715 }
1fd4e8c1 5716
e52e05ca 5717 if (GET_CODE (operands[0]) == MEM)
f2974b07 5718 {
e52e05ca
MM
5719 /* If operands[1] is a register, it may have double-precision data
5720 in it, so truncate it to single precision. We need not do
5721 this for POWERPC. */
455350f4
RK
5722 if (! TARGET_POWERPC && TARGET_HARD_FLOAT
5723 && GET_CODE (operands[1]) == REG)
e52e05ca 5724 {
455350f4
RK
5725 rtx newreg
5726 = reload_in_progress ? operands[1] : gen_reg_rtx (SFmode);
5727 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
e52e05ca
MM
5728 operands[1] = newreg;
5729 }
5730
5731 operands[1] = force_reg (SFmode, operands[1]);
f2974b07
RK
5732 }
5733
e52e05ca
MM
5734 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) < 32)
5735 {
5736 if (GET_CODE (operands[1]) == MEM
1fd4e8c1 5737#if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT && ! defined(REAL_IS_NOT_DOUBLE)
e52e05ca 5738 || GET_CODE (operands[1]) == CONST_DOUBLE
1fd4e8c1 5739#endif
e52e05ca
MM
5740 || (GET_CODE (operands[1]) == REG
5741 && (REGNO (operands[1]) < 32
5742 || (reload_in_progress
5743 && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER))))
5744 {
5745 emit_move_insn (operand_subword (operands[0], 0, 0, SFmode),
5746 operand_subword (operands[1], 0, 0, SFmode));
5747 DONE;
5748 }
5749 else
5750 {
5751 rtx stack_slot = assign_stack_temp (SFmode, 4, 0);
5752
5753 emit_move_insn (stack_slot, operands[1]);
5754 emit_move_insn (operands[0], stack_slot);
5755 DONE;
5756 }
f6ba0600 5757 }
1fd4e8c1
RK
5758 }
5759
c4c40373 5760 if (CONSTANT_P (operands[1]) && TARGET_HARD_FLOAT)
1fd4e8c1
RK
5761 {
5762 operands[1] = force_const_mem (SFmode, operands[1]);
5763 if (! memory_address_p (SFmode, XEXP (operands[1], 0))
5764 && ! reload_in_progress)
5765 operands[1] = change_address (operands[1], SFmode,
5766 XEXP (operands[1], 0));
5767 }
5768}")
5769
1fd4e8c1 5770(define_split
cd2b37d9 5771 [(set (match_operand:SF 0 "gpc_reg_operand" "")
c4c40373 5772 (match_operand:SF 1 "const_double_operand" ""))]
a260abc9 5773 "! TARGET_POWERPC64 && reload_completed
5ae4759c
MM
5774 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
5775 || (GET_CODE (operands[0]) == SUBREG
5776 && GET_CODE (SUBREG_REG (operands[0])) == REG
5777 && REGNO (SUBREG_REG (operands[0])) <= 31))"
c4c40373 5778 [(set (match_dup 2) (match_dup 3))]
685f3906
DE
5779 "
5780{
5781 long l;
5782 REAL_VALUE_TYPE rv;
5783
5784 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
5785 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
c4c40373 5786
5ae4759c 5787 operands[2] = operand_subword (operands[0], 0, 0, SFmode);
c4c40373 5788 operands[3] = GEN_INT(l);
685f3906 5789}")
7e69e155 5790
a260abc9
DE
5791(define_split
5792 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5793 (match_operand:SF 1 "const_double_operand" ""))]
5794 "TARGET_POWERPC64 && reload_completed
5795 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
5796 || (GET_CODE (operands[0]) == SUBREG
5797 && GET_CODE (SUBREG_REG (operands[0])) == REG
5798 && REGNO (SUBREG_REG (operands[0])) <= 31))"
5799 [(set (match_dup 2) (match_dup 3))]
5800 "
5801{
5802 long l;
5803 REAL_VALUE_TYPE rv;
5804
5805 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
5806 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
5807
5808 operands[2] = gen_lowpart (SImode, operands[0]);
5809 operands[3] = GEN_INT(l);
5810}")
5811
c4c40373 5812(define_insn "*movsf_hardfloat"
5ae4759c 5813 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,m,!r,!r")
c4c40373 5814 (match_operand:SF 1 "input_operand" "f,m,f,G,Fn"))]
d14a6d05
MM
5815 "(gpc_reg_operand (operands[0], SFmode)
5816 || gpc_reg_operand (operands[1], SFmode)) && TARGET_HARD_FLOAT"
1fd4e8c1
RK
5817 "@
5818 fmr %0,%1
5819 lfs%U1%X1 %0,%1
c4c40373
MM
5820 stfs%U0%X0 %1,%0
5821 #
5822 #"
5823 [(set_attr "type" "fp,fpload,fpstore,*,*")
5824 (set_attr "length" "4,4,4,4,8")])
d14a6d05 5825
c4c40373
MM
5826(define_insn "*movsf_softfloat"
5827 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,r")
5828 (match_operand:SF 1 "input_operand" "r,m,r,I,J,R,G,Fn"))]
d14a6d05
MM
5829 "(gpc_reg_operand (operands[0], SFmode)
5830 || gpc_reg_operand (operands[1], SFmode)) && TARGET_SOFT_FLOAT"
5831 "@
5832 mr %0,%1
5833 {l%U1%X1|lwz%U1%X1} %0,%1
5834 {st%U0%X0|stw%U0%X0} %1,%0
5835 {lil|li} %0,%1
802a0058 5836 {liu|lis} %0,%v1
c4c40373
MM
5837 {cal|la} %0,%1(%*)
5838 #
5839 #"
5840 [(set_attr "type" "*,load,store,*,*,*,*,*")
5841 (set_attr "length" "4,4,4,4,4,4,4,8")])
d14a6d05 5842
1fd4e8c1
RK
5843\f
5844(define_expand "movdf"
5845 [(set (match_operand:DF 0 "nonimmediate_operand" "")
5846 (match_operand:DF 1 "any_operand" ""))]
5847 ""
5848 "
5849{
e7113111
RK
5850 if (GET_CODE (operands[0]) != REG)
5851 operands[1] = force_reg (DFmode, operands[1]);
1fd4e8c1 5852
08075ead
DE
5853 /* Stores between FPR and any non-FPR registers must go through a
5854 temporary stack slot. */
5855
5856 if (TARGET_POWERPC64
5857 && GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG
5858 && ((FP_REGNO_P (REGNO (operands[0]))
5859 && ! FP_REGNO_P (REGNO (operands[1])))
5860 || (FP_REGNO_P (REGNO (operands[1]))
5861 && ! FP_REGNO_P (REGNO (operands[0])))))
5862 {
5863 rtx stack_slot = assign_stack_temp (DFmode, 8, 0);
5864
5865 emit_move_insn (stack_slot, operands[1]);
5866 emit_move_insn (operands[0], stack_slot);
5867 DONE;
5868 }
5869
e7113111 5870 if (CONSTANT_P (operands[1]) && ! easy_fp_constant (operands[1], DFmode))
1fd4e8c1
RK
5871 {
5872 operands[1] = force_const_mem (DFmode, operands[1]);
5873 if (! memory_address_p (DFmode, XEXP (operands[1], 0))
5874 && ! reload_in_progress)
5875 operands[1] = change_address (operands[1], DFmode,
5876 XEXP (operands[1], 0));
5877 }
e7113111 5878}")
1fd4e8c1
RK
5879
5880(define_split
cd2b37d9 5881 [(set (match_operand:DF 0 "gpc_reg_operand" "")
c4c40373 5882 (match_operand:DF 1 "const_int_operand" ""))]
a260abc9 5883 "! TARGET_POWERPC64 && reload_completed
5ae4759c
MM
5884 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
5885 || (GET_CODE (operands[0]) == SUBREG
5886 && GET_CODE (SUBREG_REG (operands[0])) == REG
5887 && REGNO (SUBREG_REG (operands[0])) <= 31))"
c4c40373
MM
5888 [(set (match_dup 2) (match_dup 4))
5889 (set (match_dup 3) (match_dup 1))]
5890 "
5891{
5ae4759c
MM
5892 int endian = (WORDS_BIG_ENDIAN == 0);
5893 operands[2] = operand_subword (operands[0], endian, 0, DFmode);
5894 operands[3] = operand_subword (operands[0], 1 - endian, 0, DFmode);
c4c40373
MM
5895 operands[4] = (INTVAL (operands[1]) & 0x80000000) ? constm1_rtx : const0_rtx;
5896}")
5897
c4c40373
MM
5898(define_split
5899 [(set (match_operand:DF 0 "gpc_reg_operand" "")
5900 (match_operand:DF 1 "const_double_operand" ""))]
a260abc9 5901 "! TARGET_POWERPC64 && reload_completed
5ae4759c
MM
5902 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
5903 || (GET_CODE (operands[0]) == SUBREG
5904 && GET_CODE (SUBREG_REG (operands[0])) == REG
5905 && REGNO (SUBREG_REG (operands[0])) <= 31))"
c4c40373
MM
5906 [(set (match_dup 2) (match_dup 4))
5907 (set (match_dup 3) (match_dup 5))]
5908 "
5909{
5ae4759c 5910 int endian = (WORDS_BIG_ENDIAN == 0);
47ad8c61
MM
5911 long l[2];
5912 REAL_VALUE_TYPE rv;
5913
5914 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
5915 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
5916
5ae4759c
MM
5917 operands[2] = operand_subword (operands[0], endian, 0, DFmode);
5918 operands[3] = operand_subword (operands[0], 1 - endian, 0, DFmode);
47ad8c61
MM
5919 operands[4] = GEN_INT (l[endian]);
5920 operands[5] = GEN_INT (l[1 - endian]);
c4c40373
MM
5921}")
5922
efc08378
DE
5923(define_split
5924 [(set (match_operand:DF 0 "gpc_reg_operand" "")
685f3906 5925 (match_operand:DF 1 "easy_fp_constant" ""))]
a260abc9 5926 "TARGET_POWERPC64 && reload_completed
5ae4759c
MM
5927 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
5928 || (GET_CODE (operands[0]) == SUBREG
5929 && GET_CODE (SUBREG_REG (operands[0])) == REG
5930 && REGNO (SUBREG_REG (operands[0])) <= 31))"
a260abc9 5931 [(set (match_dup 2) (match_dup 3))]
5ae4759c 5932 "
a260abc9
DE
5933{
5934 int endian = (WORDS_BIG_ENDIAN == 0);
5935 long l[2];
5936 REAL_VALUE_TYPE rv;
5937
5938 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
5939 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
5940
5941 operands[2] = gen_lowpart (DImode, operands[0]);
5942 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
5943 operands[3] = immed_double_const (l[1 - endian], l[endian], DImode);
5944}")
efc08378 5945
4eae5fe1
RK
5946;; Don't have reload use general registers to load a constant. First,
5947;; it might not work if the output operand has is the equivalent of
5948;; a non-offsettable memref, but also it is less efficient than loading
5949;; the constant into an FP register, since it will probably be used there.
5950;; The "??" is a kludge until we can figure out a more reasonable way
5951;; of handling these non-offsettable values.
c4c40373
MM
5952(define_insn "*movdf_hardfloat32"
5953 [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,o,!r,!r,!r,f,f,m")
5954 (match_operand:DF 1 "input_operand" "r,o,r,G,H,F,f,m,f"))]
dc4f83ca
MM
5955 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
5956 && (register_operand (operands[0], DFmode)
5957 || register_operand (operands[1], DFmode))"
e7113111
RK
5958 "*
5959{
5960 switch (which_alternative)
5961 {
a260abc9
DE
5962 default:
5963 abort();
e7113111
RK
5964 case 0:
5965 /* We normally copy the low-numbered register first. However, if
5966 the first register operand 0 is the same as the second register of
5967 operand 1, we must copy in the opposite order. */
5968 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
deb9225a 5969 return \"mr %L0,%L1\;mr %0,%1\";
e7113111 5970 else
deb9225a 5971 return \"mr %0,%1\;mr %L0,%L1\";
e7113111
RK
5972 case 1:
5973 /* If the low-address word is used in the address, we must load it
5974 last. Otherwise, load it first. Note that we cannot have
5975 auto-increment in that case since the address register is known to be
5976 dead. */
5977 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
5978 operands [1], 0))
ca7f5001 5979 return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
e7113111 5980 else
ca7f5001 5981 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
e7113111 5982 case 2:
ca7f5001 5983 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
e7113111 5984 case 3:
e7113111 5985 case 4:
e7113111 5986 case 5:
c4c40373 5987 return \"#\";
e7113111 5988 case 6:
c4c40373
MM
5989 return \"fmr %0,%1\";
5990 case 7:
5991 return \"lfd%U1%X1 %0,%1\";
5992 case 8:
e7113111
RK
5993 return \"stfd%U0%X0 %1,%0\";
5994 }
5995}"
c4c40373
MM
5996 [(set_attr "type" "*,load,store,*,*,*,fp,fpload,fpstore")
5997 (set_attr "length" "8,8,8,8,12,16,*,*,*")])
51b8fc2c 5998
c4c40373
MM
5999(define_insn "*movdf_softfloat32"
6000 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,o,r,r,r")
6001 (match_operand:DF 1 "input_operand" "r,o,r,G,H,F"))]
dc4f83ca
MM
6002 "! TARGET_POWERPC64 && TARGET_SOFT_FLOAT
6003 && (register_operand (operands[0], DFmode)
6004 || register_operand (operands[1], DFmode))"
6005 "*
6006{
6007 switch (which_alternative)
6008 {
a260abc9
DE
6009 default:
6010 abort();
dc4f83ca
MM
6011 case 0:
6012 /* We normally copy the low-numbered register first. However, if
6013 the first register operand 0 is the same as the second register of
6014 operand 1, we must copy in the opposite order. */
6015 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
6016 return \"mr %L0,%L1\;mr %0,%1\";
6017 else
6018 return \"mr %0,%1\;mr %L0,%L1\";
6019 case 1:
6020 /* If the low-address word is used in the address, we must load it
6021 last. Otherwise, load it first. Note that we cannot have
6022 auto-increment in that case since the address register is known to be
6023 dead. */
6024 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
6025 operands [1], 0))
6026 return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
6027 else
6028 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
6029 case 2:
6030 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
6031 case 3:
c4c40373
MM
6032 case 4:
6033 case 5:
dc4f83ca
MM
6034 return \"#\";
6035 }
6036}"
c4c40373
MM
6037 [(set_attr "type" "*,load,store,*,*,*")
6038 (set_attr "length" "8,8,8,8,12,16")])
dc4f83ca 6039
c4c40373
MM
6040(define_insn "*movdf_hardfloat64"
6041 [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,o,!r,!r,!r,f,f,m")
6042 (match_operand:DF 1 "input_operand" "r,o,r,G,H,F,f,m,f"))]
dc4f83ca
MM
6043 "TARGET_POWERPC64 && TARGET_HARD_FLOAT
6044 && (register_operand (operands[0], DFmode)
6045 || register_operand (operands[1], DFmode))"
51b8fc2c 6046 "@
3d5570cb
RK
6047 mr %0,%1
6048 ld%U1%X1 %0,%1
96bb8ed3 6049 std%U0%X0 %1,%0
3d5570cb 6050 #
c4c40373
MM
6051 #
6052 #
3d5570cb 6053 fmr %0,%1
f63184ac 6054 lfd%U1%X1 %0,%1
3d5570cb 6055 stfd%U0%X0 %1,%0"
c4c40373
MM
6056 [(set_attr "type" "*,load,store,*,*,*,fp,fpload,fpstore")
6057 (set_attr "length" "4,4,4,8,12,16,4,4,4")])
dc4f83ca 6058
c4c40373
MM
6059(define_insn "*movdf_softfloat64"
6060 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,o,r,r,r")
6061 (match_operand:DF 1 "input_operand" "r,o,r,G,H,F"))]
dc4f83ca
MM
6062 "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
6063 && (register_operand (operands[0], DFmode)
6064 || register_operand (operands[1], DFmode))"
6065 "@
6066 mr %0,%1
6067 ld%U1%X1 %0,%1
96bb8ed3 6068 std%U0%X0 %1,%0
c4c40373
MM
6069 #
6070 #
dc4f83ca 6071 #"
c4c40373
MM
6072 [(set_attr "type" "*,load,store,*,*,*")
6073 (set_attr "length" "*,*,*,8,12,16")])
1fd4e8c1
RK
6074\f
6075;; Next come the multi-word integer load and store and the load and store
6076;; multiple insns.
6077(define_expand "movdi"
6078 [(set (match_operand:DI 0 "general_operand" "")
e6ca2c17 6079 (match_operand:DI 1 "any_operand" ""))]
1fd4e8c1
RK
6080 ""
6081 "
6082{
e6ca2c17 6083 if (GET_CODE (operands[0]) != REG)
6b6ccd10
RK
6084 operands[1] = force_reg (DImode, operands[1]);
6085
a260abc9
DE
6086 /* Convert a move of a CONST_DOUBLE into a CONST_INT
6087 only if sign-extended lower-half for 32-bit host. */
6088 if (GET_CODE (operands[1]) == CONST_DOUBLE
e8d791dd 6089#if HOST_BITS_PER_WIDE_INT == 32
a260abc9
DE
6090 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
6091 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
6092 || (CONST_DOUBLE_HIGH (operands[1]) == 0xffffffff
6093 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
e8d791dd 6094#endif
a260abc9
DE
6095 )
6096 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
6b6ccd10 6097
a260abc9
DE
6098 if (TARGET_64BIT
6099 && CONSTANT_P (operands[1])
6100#if HOST_BITS_PER_WIDE_INT == 32
6101 && GET_CODE (operands[1]) != CONST_INT
6102#endif
6103 && ! easy_fp_constant (operands[1], DImode)
6104 && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1]))
6105 {
6106 /* Emit a USE operation so that the constant isn't deleted if
6107 expensive optimizations are turned on because nobody
6108 references it. This should only be done for operands that
6109 contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set.
6110 This should not be done for operands that contain LABEL_REFs.
6111 For now, we just handle the obvious case. */
6112 if (GET_CODE (operands[1]) != LABEL_REF)
6113 emit_insn (gen_rtx (USE, VOIDmode, operands[1]));
062284d8 6114
a260abc9
DE
6115 /* If we are to limit the number of things we put in the TOC and
6116 this is a symbol plus a constant we can add in one insn,
6117 just put the symbol in the TOC and add the constant. Don't do
6118 this if reload is in progress. */
6119 if (GET_CODE (operands[1]) == CONST
6120 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
6121 && GET_CODE (XEXP (operands[1], 0)) == PLUS
6122 && add_operand (XEXP (XEXP (operands[1], 0), 1), DImode)
6123 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
6124 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
6125 && ! side_effects_p (operands[0]))
6126 {
6127 rtx sym = force_const_mem (DImode, XEXP (XEXP (operands[1], 0), 0));
6128 rtx other = XEXP (XEXP (operands[1], 0), 1);
a473029f 6129
a260abc9
DE
6130 emit_insn (gen_adddi3 (operands[0], force_reg (DImode, sym), other));
6131 DONE;
6132 }
a473029f 6133
a260abc9
DE
6134 operands[1] = force_const_mem (DImode, operands[1]);
6135 if (! memory_address_p (DImode, XEXP (operands[1], 0))
6136 && ! reload_in_progress)
6137 operands[1] = change_address (operands[1], DImode,
6138 XEXP (operands[1], 0));
a473029f 6139 }
1fd4e8c1
RK
6140}")
6141
c4c40373 6142(define_insn "*movdi_32"
4e74d8ec
MM
6143 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,f,f,m,r,r,r,r,r")
6144 (match_operand:DI 1 "input_operand" "r,m,r,f,m,f,IJK,n,G,H,F"))]
a260abc9 6145 "! TARGET_POWERPC64
4e74d8ec
MM
6146 && (gpc_reg_operand (operands[0], DImode)
6147 || gpc_reg_operand (operands[1], DImode))"
1fd4e8c1
RK
6148 "*
6149{
6150 switch (which_alternative)
6151 {
a260abc9
DE
6152 default:
6153 abort();
1fd4e8c1
RK
6154 case 0:
6155 /* We normally copy the low-numbered register first. However, if
6156 the first register operand 0 is the same as the second register of
6157 operand 1, we must copy in the opposite order. */
6158 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
deb9225a 6159 return \"mr %L0,%L1\;mr %0,%1\";
1fd4e8c1 6160 else
deb9225a 6161 return \"mr %0,%1\;mr %L0,%L1\";
1fd4e8c1
RK
6162 case 1:
6163 /* If the low-address word is used in the address, we must load it
6164 last. Otherwise, load it first. Note that we cannot have
6165 auto-increment in that case since the address register is known to be
6166 dead. */
6167 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
6168 operands [1], 0))
ca7f5001 6169 return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
1fd4e8c1 6170 else
ca7f5001 6171 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
1fd4e8c1 6172 case 2:
ca7f5001 6173 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
8ffd9c51
RK
6174 case 3:
6175 return \"fmr %0,%1\";
6176 case 4:
6177 return \"lfd%U1%X1 %0,%1\";
6178 case 5:
6179 return \"stfd%U0%X0 %1,%0\";
4e74d8ec
MM
6180 case 6:
6181 case 7:
6182 case 8:
6183 case 9:
6184 case 10:
6185 return \"#\";
1fd4e8c1
RK
6186 }
6187}"
4e74d8ec
MM
6188 [(set_attr "type" "*,load,store,fp,fpload,fpstore,*,*,*,*,*")
6189 (set_attr "length" "8,8,8,*,*,*,8,12,8,12,16")])
6190
6191(define_split
6192 [(set (match_operand:DI 0 "gpc_reg_operand" "")
6193 (match_operand:DI 1 "const_int_operand" ""))]
a260abc9 6194 "! TARGET_POWERPC64 && reload_completed"
4e74d8ec
MM
6195 [(set (match_dup 2) (match_dup 4))
6196 (set (match_dup 3) (match_dup 1))]
6197 "
6198{
6199 operands[2] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0);
6200 operands[3] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0);
6201 operands[4] = (INTVAL (operands[1]) & 0x80000000) ? constm1_rtx : const0_rtx;
6202}")
6203
4e74d8ec
MM
6204(define_split
6205 [(set (match_operand:DI 0 "gpc_reg_operand" "")
6206 (match_operand:DI 1 "const_double_operand" ""))]
a260abc9 6207 "! TARGET_POWERPC64 && reload_completed"
4e74d8ec
MM
6208 [(set (match_dup 2) (match_dup 4))
6209 (set (match_dup 3) (match_dup 5))]
6210 "
6211{
6212 operands[2] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0);
6213 operands[3] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0);
f6968f59
MM
6214 operands[4] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
6215 operands[5] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
4e74d8ec
MM
6216}")
6217
c4c40373 6218(define_insn "*movdi_64"
e6ca2c17 6219 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,f,f,m,r,*h,*h")
4e74d8ec 6220 (match_operand:DI 1 "input_operand" "r,m,r,I,J,nF,R,f,m,f,*h,r,0"))]
a260abc9 6221 "TARGET_POWERPC64
4e74d8ec
MM
6222 && (gpc_reg_operand (operands[0], DImode)
6223 || gpc_reg_operand (operands[1], DImode))"
51b8fc2c 6224 "@
3d5570cb
RK
6225 mr %0,%1
6226 ld%U1%X1 %0,%1
96bb8ed3 6227 std%U0%X0 %1,%0
3d5570cb 6228 li %0,%1
802a0058 6229 lis %0,%v1
e6ca2c17 6230 #
57fa6739 6231 {cal|la} %0,%1(%*)
3d5570cb
RK
6232 fmr %0,%1
6233 lfd%U1%X1 %0,%1
6234 stfd%U0%X0 %1,%0
6235 mf%1 %0
08075ead
DE
6236 mt%0 %1
6237 cror 0,0,0"
b7ff3d82 6238 [(set_attr "type" "*,load,store,*,*,*,*,fp,fpload,fpstore,*,mtjmpr,*")
e6ca2c17
DE
6239 (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4")])
6240
a260abc9
DE
6241(define_insn ""
6242 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
6243 (match_operand:DI 1 "const_double_operand" "F"))]
6244 "TARGET_POWERPC64 && GET_CODE (operands[1]) == CONST_DOUBLE
6245 && num_insns_constant (operands[1], DImode) == 1"
6246 "*
6247{
6248 return ((unsigned HOST_WIDE_INT)
6249 (CONST_DOUBLE_LOW (operands[1]) + 0x8000) < 0x10000)
6250 ? \"li %0,%1\" : \"lis %0,%v1\";
6251}")
6252
6253(define_split
6254 [(set (match_operand:DI 0 "gpc_reg_operand" "")
6255 (match_operand:DI 1 "const_int_operand" ""))]
6256 "HOST_BITS_PER_WIDE_INT == 32 && TARGET_POWERPC64
6257 && num_insns_constant (operands[1], DImode) > 1"
6258 [(set (match_dup 0)
6259 (match_dup 2))
6260 (set (match_dup 0)
6261 (ior:DI (match_dup 0)
6262 (match_dup 3)))]
6263 "
6264{
6265 operands[2] = GEN_INT (INTVAL (operands[1]) & 0xffff0000);
6266 operands[3] = GEN_INT (INTVAL (operands[1]) & 0xffff);
6267}")
e6ca2c17
DE
6268
6269(define_split
6270 [(set (match_operand:DI 0 "gpc_reg_operand" "")
6271 (match_operand:DI 1 "const_double_operand" ""))]
a260abc9
DE
6272 "HOST_BITS_PER_WIDE_INT == 32 && TARGET_POWERPC64
6273 && GET_CODE (operands[1]) == CONST_DOUBLE
6274 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
6275 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
6276 || (CONST_DOUBLE_HIGH (operands[1]) == 0xffffffff
6277 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))"
e6ca2c17
DE
6278 [(set (match_dup 0)
6279 (match_dup 2))
6280 (set (match_dup 0)
6281 (ior:DI (match_dup 0)
a260abc9
DE
6282 (match_dup 3)))]
6283 "
6284{
6285 operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[1]) & 0xffff0000);
6286 operands[3] = GEN_INT (CONST_DOUBLE_LOW (operands[1]) & 0xffff);
6287}")
6288
6289(define_split
6290 [(set (match_operand:DI 0 "gpc_reg_operand" "")
6291 (match_operand:DI 1 "const_double_operand" ""))]
6292 "HOST_BITS_PER_WIDE_INT == 32 && TARGET_POWERPC64
6293 && GET_CODE (operands[1]) == CONST_DOUBLE
6294 && CONST_DOUBLE_HIGH (operands[1]) == 0
6295 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0"
6296 [(set (match_dup 0)
6297 (match_dup 2))
6298 (set (match_dup 0)
6299 (zero_extend:DI (subreg:SI (match_dup 0) 0)))]
6300 "
6301{ operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[1])); }")
6302
6303(define_split
6304 [(set (match_operand:DI 0 "gpc_reg_operand" "")
6305 (match_operand:DI 1 "const_double_operand" ""))]
6306 "HOST_BITS_PER_WIDE_INT == 32 && TARGET_POWERPC64
6307 && GET_CODE (operands[1]) == CONST_DOUBLE
6308 && CONST_DOUBLE_LOW (operands[1]) == 0"
6309 [(set (match_dup 0)
6310 (match_dup 2))
e6ca2c17
DE
6311 (set (match_dup 0)
6312 (ashift:DI (match_dup 0)
a260abc9
DE
6313 (const_int 32)))]
6314 "
6315{ operands[2] = GEN_INT (CONST_DOUBLE_HIGH (operands[1])); }")
6316
6317;; Generate all one-bits and clear left or right.
6318;; Use (and:DI (rotate:DI ...)) to avoid anddi3 unnecessary clobber.
6319(define_split
6320 [(set (match_operand:DI 0 "gpc_reg_operand" "")
6321 (match_operand:DI 1 "mask64_operand" ""))]
6322 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
6323 [(set (match_dup 0) (const_int -1))
e6ca2c17 6324 (set (match_dup 0)
a260abc9
DE
6325 (and:DI (rotate:DI (match_dup 0)
6326 (const_int 0))
6327 (match_dup 1)))]
6328 "")
6329
6330;; Split a load of a large constant into the appropriate five-instruction
6331;; sequence. Handle anything in a constant number of insns.
6332;; When non-easy constants can go in the TOC, this should use
6333;; easy_fp_constant predicate.
6334(define_split
6335 [(set (match_operand:DI 0 "gpc_reg_operand" "")
6336 (match_operand:DI 1 "const_double_operand" ""))]
6337 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
6338 [(set (match_dup 0)
6339 (match_dup 2))
6340 (set (match_dup 0)
6341 (ashift:DI (match_dup 0)
6342 (const_int 32)))
e6ca2c17
DE
6343 (set (match_dup 0)
6344 (ior:DI (match_dup 0)
a260abc9 6345 (match_dup 3)))]
e6ca2c17
DE
6346 "
6347{
6348 HOST_WIDE_INT low;
6349 HOST_WIDE_INT high;
6350
6351 if (GET_CODE (operands[1]) == CONST_DOUBLE)
6352 {
f6968f59
MM
6353 low = CONST_DOUBLE_LOW (operands[1]);
6354 high = CONST_DOUBLE_HIGH (operands[1]);
e6ca2c17 6355 }
e8d791dd
DE
6356 else
6357#if HOST_BITS_PER_WIDE_INT == 32
e6ca2c17
DE
6358 {
6359 low = INTVAL (operands[1]);
6360 high = (low < 0) ? ~0 : 0;
6361 }
e8d791dd 6362#else
e6ca2c17
DE
6363 {
6364 low = INTVAL (operands[1]) & 0xffffffff;
f4558646 6365 high = (HOST_WIDE_INT) INTVAL (operands[1]) >> 32;
e6ca2c17 6366 }
e8d791dd 6367#endif
e6ca2c17 6368
a260abc9
DE
6369 operands[2] = GEN_INT (high);
6370 operands[3] = GEN_INT (low);
e6ca2c17 6371}")
08075ead
DE
6372
6373(define_insn ""
6374 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
6375 (compare:CC (match_operand:DI 1 "gpc_reg_operand" "r")
6376 (const_int 0)))
6377 (set (match_operand:DI 0 "gpc_reg_operand" "=r") (match_dup 1))]
6378 "TARGET_POWERPC64"
6379 "mr. %0,%1"
6380 [(set_attr "type" "compare")])
1fd4e8c1
RK
6381\f
6382;; TImode is similar, except that we usually want to compute the address into
6383;; a register and use lsi/stsi (the exception is during reload). MQ is also
ca7f5001 6384;; clobbered in stsi for POWER, so we need a SCRATCH for it.
1fd4e8c1
RK
6385(define_expand "movti"
6386 [(parallel [(set (match_operand:TI 0 "general_operand" "")
6387 (match_operand:TI 1 "general_operand" ""))
6388 (clobber (scratch:SI))])]
7e69e155 6389 "TARGET_STRING || TARGET_POWERPC64"
1fd4e8c1
RK
6390 "
6391{
6392 if (GET_CODE (operands[0]) == MEM)
6393 operands[1] = force_reg (TImode, operands[1]);
6394
6395 if (GET_CODE (operands[0]) == MEM
6396 && GET_CODE (XEXP (operands[0], 0)) != REG
6397 && ! reload_in_progress)
6398 operands[0] = change_address (operands[0], TImode,
6399 copy_addr_to_reg (XEXP (operands[0], 0)));
6400
6401 if (GET_CODE (operands[1]) == MEM
6402 && GET_CODE (XEXP (operands[1], 0)) != REG
6403 && ! reload_in_progress)
6404 operands[1] = change_address (operands[1], TImode,
6405 copy_addr_to_reg (XEXP (operands[1], 0)));
6406}")
6407
6408;; We say that MQ is clobbered in the last alternative because the first
6409;; alternative would never get used otherwise since it would need a reload
6410;; while the 2nd alternative would not. We put memory cases first so they
6411;; are preferred. Otherwise, we'd try to reload the output instead of
6412;; giving the SCRATCH mq.
a260abc9 6413(define_insn "*movti_power"
e1469d0d 6414 [(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,m,????r,????r,????r")
1fd4e8c1
RK
6415 (match_operand:TI 1 "reg_or_mem_operand" "r,r,r,Q,m"))
6416 (clobber (match_scratch:SI 2 "=q,q#X,X,X,X"))]
7e69e155 6417 "TARGET_STRING && TARGET_POWER && ! TARGET_POWERPC64
dc4f83ca 6418 && (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))"
1fd4e8c1
RK
6419 "*
6420{
6421 switch (which_alternative)
6422 {
dc4f83ca
MM
6423 default:
6424 abort ();
6425
1fd4e8c1 6426 case 0:
ca7f5001 6427 return \"{stsi|stswi} %1,%P0,16\";
1fd4e8c1
RK
6428
6429 case 1:
ca7f5001 6430 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\;{st|stw} %Y1,%Y0\;{st|stw} %Z1,%Z0\";
1fd4e8c1
RK
6431
6432 case 2:
6433 /* Normally copy registers with lowest numbered register copied first.
6434 But copy in the other order if the first register of the output
6435 is the second, third, or fourth register in the input. */
6436 if (REGNO (operands[0]) >= REGNO (operands[1]) + 1
6437 && REGNO (operands[0]) <= REGNO (operands[1]) + 3)
deb9225a 6438 return \"mr %Z0,%Z1\;mr %Y0,%Y1\;mr %L0,%L1\;mr %0,%1\";
1fd4e8c1 6439 else
deb9225a 6440 return \"mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1\";
1fd4e8c1
RK
6441 case 3:
6442 /* If the address is not used in the output, we can use lsi. Otherwise,
6443 fall through to generating four loads. */
6444 if (! reg_overlap_mentioned_p (operands[0], operands[1]))
ca7f5001 6445 return \"{lsi|lswi} %0,%P1,16\";
1fd4e8c1
RK
6446 /* ... fall through ... */
6447 case 4:
6448 /* If the address register is the same as the register for the lowest-
6449 addressed word, load it last. Similarly for the next two words.
6450 Otherwise load lowest address to highest. */
6451 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
6452 operands[1], 0))
ca7f5001 6453 return \"{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %0,%1\";
1fd4e8c1
RK
6454 else if (refers_to_regno_p (REGNO (operands[0]) + 1,
6455 REGNO (operands[0]) + 2, operands[1], 0))
ca7f5001 6456 return \"{l|lwz} %0,%1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %L0,%L1\";
1fd4e8c1
RK
6457 else if (refers_to_regno_p (REGNO (operands[0]) + 2,
6458 REGNO (operands[0]) + 3, operands[1], 0))
ca7f5001 6459 return \"{l|lwz} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Z0,%Z1\;{l|lwz} %Y0,%Y1\";
1fd4e8c1 6460 else
ca7f5001 6461 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\";
1fd4e8c1
RK
6462 }
6463}"
b7ff3d82 6464 [(set_attr "type" "store,store,*,load,load")
b19003d8 6465 (set_attr "length" "*,16,16,*,16")])
51b8fc2c 6466
a260abc9 6467(define_insn "*movti_string"
dc4f83ca
MM
6468 [(set (match_operand:TI 0 "reg_or_mem_operand" "=m,????r,????r")
6469 (match_operand:TI 1 "reg_or_mem_operand" "r,r,m"))
6470 (clobber (match_scratch:SI 2 "=X,X,X"))]
7e69e155 6471 "TARGET_STRING && !TARGET_POWER && ! TARGET_POWERPC64
dc4f83ca
MM
6472 && (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))"
6473 "*
6474{
6475 switch (which_alternative)
6476 {
6477 default:
6478 abort ();
6479
6480 case 0:
6481 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\;{st|stw} %Y1,%Y0\;{st|stw} %Z1,%Z0\";
6482
6483 case 1:
6484 /* Normally copy registers with lowest numbered register copied first.
6485 But copy in the other order if the first register of the output
6486 is the second, third, or fourth register in the input. */
6487 if (REGNO (operands[0]) >= REGNO (operands[1]) + 1
6488 && REGNO (operands[0]) <= REGNO (operands[1]) + 3)
6489 return \"mr %Z0,%Z1\;mr %Y0,%Y1\;mr %L0,%L1\;mr %0,%1\";
6490 else
6491 return \"mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1\";
6492 case 2:
6493 /* If the address register is the same as the register for the lowest-
6494 addressed word, load it last. Similarly for the next two words.
6495 Otherwise load lowest address to highest. */
6496 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
6497 operands[1], 0))
6498 return \"{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %0,%1\";
6499 else if (refers_to_regno_p (REGNO (operands[0]) + 1,
6500 REGNO (operands[0]) + 2, operands[1], 0))
6501 return \"{l|lwz} %0,%1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %L0,%L1\";
6502 else if (refers_to_regno_p (REGNO (operands[0]) + 2,
6503 REGNO (operands[0]) + 3, operands[1], 0))
6504 return \"{l|lwz} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Z0,%Z1\;{l|lwz} %Y0,%Y1\";
6505 else
6506 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\";
6507 }
6508}"
b7ff3d82 6509 [(set_attr "type" "store,*,load")
dc4f83ca
MM
6510 (set_attr "length" "16,16,16")])
6511
a260abc9 6512(define_insn "*movti_ppc64"
51b8fc2c
RK
6513 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m")
6514 (match_operand:TI 1 "input_operand" "r,m,r"))]
6515 "TARGET_POWERPC64 && (gpc_reg_operand (operands[0], TImode)
6516 || gpc_reg_operand (operands[1], TImode))"
6517 "*
6518{
6519 switch (which_alternative)
6520 {
a260abc9
DE
6521 default:
6522 abort();
51b8fc2c
RK
6523 case 0:
6524 /* We normally copy the low-numbered register first. However, if
6525 the first register operand 0 is the same as the second register of
6526 operand 1, we must copy in the opposite order. */
6527 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
6528 return \"mr %L0,%L1\;mr %0,%1\";
6529 else
6530 return \"mr %0,%1\;mr %L0,%L1\";
6531 case 1:
6532 /* If the low-address word is used in the address, we must load it
6533 last. Otherwise, load it first. Note that we cannot have
6534 auto-increment in that case since the address register is known to be
6535 dead. */
6536 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
6537 operands [1], 0))
6538 return \"ld %L0,%L1\;ld %0,%1\";
6539 else
6540 return \"ld%U1 %0,%1\;ld %L0,%L1\";
6541 case 2:
6542 return \"std%U0 %1,%0\;std %L1,%L0\";
6543 }
6544}"
b7ff3d82 6545 [(set_attr "type" "*,load,store")
51b8fc2c 6546 (set_attr "length" "8,8,8")])
1fd4e8c1
RK
6547\f
6548(define_expand "load_multiple"
2f622005
RK
6549 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6550 (match_operand:SI 1 "" ""))
6551 (use (match_operand:SI 2 "" ""))])]
7e69e155 6552 "TARGET_STRING"
1fd4e8c1
RK
6553 "
6554{
6555 int regno;
6556 int count;
6557 rtx from;
6558 int i;
6559
6560 /* Support only loading a constant number of fixed-point registers from
6561 memory and only bother with this if more than two; the machine
6562 doesn't support more than eight. */
6563 if (GET_CODE (operands[2]) != CONST_INT
6564 || INTVAL (operands[2]) <= 2
6565 || INTVAL (operands[2]) > 8
6566 || GET_CODE (operands[1]) != MEM
6567 || GET_CODE (operands[0]) != REG
6568 || REGNO (operands[0]) >= 32)
6569 FAIL;
6570
6571 count = INTVAL (operands[2]);
6572 regno = REGNO (operands[0]);
6573
6574 operands[3] = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (count));
6575 from = force_reg (SImode, XEXP (operands[1], 0));
6576
6577 for (i = 0; i < count; i++)
6578 XVECEXP (operands[3], 0, i)
6579 = gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, regno + i),
538bb158
JW
6580 change_address (operands[1], SImode,
6581 plus_constant (from, i * 4)));
1fd4e8c1
RK
6582}")
6583
6584(define_insn ""
6585 [(match_parallel 0 "load_multiple_operation"
cd2b37d9 6586 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
4c99e795 6587 (mem:SI (match_operand:SI 2 "register_operand" "b")))])]
7e69e155 6588 "TARGET_STRING"
1fd4e8c1
RK
6589 "*
6590{
6591 /* We have to handle the case where the pseudo used to contain the address
e82ee4cc
RK
6592 is assigned to one of the output registers. */
6593 int i, j;
6594 int words = XVECLEN (operands[0], 0);
6595 rtx xop[10];
6596
6597 if (XVECLEN (operands[0], 0) == 1)
6598 return \"{l|lwz} %1,0(%2)\";
1fd4e8c1 6599
e82ee4cc 6600 for (i = 0; i < words; i++)
1fd4e8c1
RK
6601 if (refers_to_regno_p (REGNO (operands[1]) + i,
6602 REGNO (operands[1]) + i + 1, operands[2], 0))
6603 {
e82ee4cc
RK
6604 if (i == words-1)
6605 {
6606 xop[0] = operands[1];
6607 xop[1] = operands[2];
6608 xop[2] = GEN_INT (4 * (words-1));
d89ddcfd 6609 output_asm_insn (\"{lsi|lswi} %0,%1,%2\;{l|lwz} %1,%2(%1)\", xop);
e82ee4cc
RK
6610 return \"\";
6611 }
6612 else if (i == 0)
6613 {
6614 xop[0] = operands[1];
6615 xop[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
6616 xop[2] = GEN_INT (4 * (words-1));
6617 output_asm_insn (\"{cal %0,4(%0)|addi %0,%0,4}\;{lsi|lswi} %1,%0,%2\;{l|lwz} %0,-4(%0)\", xop);
6618 return \"\";
6619 }
6620 else
6621 {
6622 for (j = 0; j < words; j++)
6623 if (j != i)
6624 {
6625 xop[0] = gen_rtx (REG, SImode, REGNO (operands[1]) + j);
6626 xop[1] = operands[2];
6627 xop[2] = GEN_INT (j * 4);
6628 output_asm_insn (\"{l|lwz} %0,%2(%1)\", xop);
6629 }
6630 xop[0] = operands[2];
6631 xop[1] = GEN_INT (i * 4);
6632 output_asm_insn (\"{l|lwz} %0,%1(%0)\", xop);
6633 return \"\";
6634 }
1fd4e8c1
RK
6635 }
6636
e82ee4cc 6637 return \"{lsi|lswi} %1,%2,%N0\";
1fd4e8c1 6638}"
b19003d8 6639 [(set_attr "type" "load")
e82ee4cc 6640 (set_attr "length" "32")])
b19003d8 6641
b7ff3d82 6642\f
1fd4e8c1 6643(define_expand "store_multiple"
2f622005
RK
6644 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6645 (match_operand:SI 1 "" ""))
6646 (clobber (scratch:SI))
6647 (use (match_operand:SI 2 "" ""))])]
7e69e155 6648 "TARGET_STRING"
1fd4e8c1
RK
6649 "
6650{
6651 int regno;
6652 int count;
6653 rtx to;
6654 int i;
6655
6656 /* Support only storing a constant number of fixed-point registers to
6657 memory and only bother with this if more than two; the machine
6658 doesn't support more than eight. */
6659 if (GET_CODE (operands[2]) != CONST_INT
6660 || INTVAL (operands[2]) <= 2
6661 || INTVAL (operands[2]) > 8
6662 || GET_CODE (operands[0]) != MEM
6663 || GET_CODE (operands[1]) != REG
6664 || REGNO (operands[1]) >= 32)
6665 FAIL;
6666
6667 count = INTVAL (operands[2]);
6668 regno = REGNO (operands[1]);
6669
6670 operands[3] = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (count + 1));
6671 to = force_reg (SImode, XEXP (operands[0], 0));
6672
6673 XVECEXP (operands[3], 0, 0)
538bb158
JW
6674 = gen_rtx (SET, VOIDmode, change_address (operands[0], SImode, to),
6675 operands[1]);
1fd4e8c1
RK
6676 XVECEXP (operands[3], 0, 1) = gen_rtx (CLOBBER, VOIDmode,
6677 gen_rtx (SCRATCH, SImode));
6678
6679 for (i = 1; i < count; i++)
6680 XVECEXP (operands[3], 0, i + 1)
6681 = gen_rtx (SET, VOIDmode,
538bb158
JW
6682 change_address (operands[0], SImode,
6683 plus_constant (to, i * 4)),
1fd4e8c1
RK
6684 gen_rtx (REG, SImode, regno + i));
6685}")
6686
6687(define_insn ""
6688 [(match_parallel 0 "store_multiple_operation"
6689 [(set (match_operand:SI 1 "indirect_operand" "=Q")
cd2b37d9 6690 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 6691 (clobber (match_scratch:SI 3 "=q"))])]
7e69e155 6692 "TARGET_STRING && TARGET_POWER"
b7ff3d82
DE
6693 "{stsi|stswi} %2,%P1,%O0"
6694 [(set_attr "type" "store")])
d14a6d05
MM
6695
6696(define_insn ""
6697 [(match_parallel 0 "store_multiple_operation"
4c99e795 6698 [(set (mem:SI (match_operand:SI 1 "register_operand" "b"))
d14a6d05
MM
6699 (match_operand:SI 2 "gpc_reg_operand" "r"))
6700 (clobber (match_scratch:SI 3 "X"))])]
7e69e155 6701 "TARGET_STRING && !TARGET_POWER"
b7ff3d82
DE
6702 "{stsi|stswi} %2,%1,%O0"
6703 [(set_attr "type" "store")])
7e69e155
MM
6704
6705\f
6706;; String/block move insn.
6707;; Argument 0 is the destination
6708;; Argument 1 is the source
6709;; Argument 2 is the length
6710;; Argument 3 is the alignment
6711
6712(define_expand "movstrsi"
b6c9286a
MM
6713 [(parallel [(set (match_operand:BLK 0 "" "")
6714 (match_operand:BLK 1 "" ""))
6715 (use (match_operand:SI 2 "" ""))
6716 (use (match_operand:SI 3 "" ""))])]
7e69e155
MM
6717 ""
6718 "
6719{
6720 if (expand_block_move (operands))
6721 DONE;
6722 else
6723 FAIL;
6724}")
6725
6726;; Move up to 32 bytes at a time. The fixed registers are needed because the
6727;; register allocator doesn't have a clue about allocating 8 word registers
6728(define_expand "movstrsi_8reg"
b6c9286a
MM
6729 [(parallel [(set (match_operand 0 "" "")
6730 (match_operand 1 "" ""))
6731 (use (match_operand 2 "" ""))
6732 (use (match_operand 3 "" ""))
7e69e155
MM
6733 (clobber (reg:SI 5))
6734 (clobber (reg:SI 6))
6735 (clobber (reg:SI 7))
6736 (clobber (reg:SI 8))
6737 (clobber (reg:SI 9))
6738 (clobber (reg:SI 10))
6739 (clobber (reg:SI 11))
6740 (clobber (reg:SI 12))
3c67b673 6741 (clobber (match_scratch:SI 4 ""))])]
7e69e155
MM
6742 "TARGET_STRING"
6743 "")
6744
6745(define_insn ""
3c67b673
RK
6746 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6747 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6748 (use (match_operand:SI 2 "immediate_operand" "i"))
6749 (use (match_operand:SI 3 "immediate_operand" "i"))
6750 (clobber (match_operand:SI 4 "register_operand" "=r"))
7e69e155
MM
6751 (clobber (reg:SI 6))
6752 (clobber (reg:SI 7))
6753 (clobber (reg:SI 8))
6754 (clobber (reg:SI 9))
6755 (clobber (reg:SI 10))
6756 (clobber (reg:SI 11))
6757 (clobber (reg:SI 12))
3c67b673 6758 (clobber (match_scratch:SI 5 "=q"))]
7e69e155
MM
6759 "TARGET_STRING && TARGET_POWER
6760 && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32) || INTVAL (operands[2]) == 0)
6761 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
6762 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
3c67b673
RK
6763 && REGNO (operands[4]) == 5"
6764 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
b7ff3d82
DE
6765 [(set_attr "type" "load")
6766 (set_attr "length" "8")])
7e69e155
MM
6767
6768(define_insn ""
3c67b673
RK
6769 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6770 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6771 (use (match_operand:SI 2 "immediate_operand" "i"))
6772 (use (match_operand:SI 3 "immediate_operand" "i"))
6773 (clobber (match_operand:SI 4 "register_operand" "=r"))
7e69e155
MM
6774 (clobber (reg:SI 6))
6775 (clobber (reg:SI 7))
6776 (clobber (reg:SI 8))
6777 (clobber (reg:SI 9))
6778 (clobber (reg:SI 10))
6779 (clobber (reg:SI 11))
6780 (clobber (reg:SI 12))
3c67b673 6781 (clobber (match_scratch:SI 5 "X"))]
7e69e155
MM
6782 "TARGET_STRING && !TARGET_POWER
6783 && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32) || INTVAL (operands[2]) == 0)
6784 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
6785 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
3c67b673
RK
6786 && REGNO (operands[4]) == 5"
6787 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
b7ff3d82
DE
6788 [(set_attr "type" "load")
6789 (set_attr "length" "8")])
7e69e155
MM
6790
6791;; Move up to 24 bytes at a time. The fixed registers are needed because the
6792;; register allocator doesn't have a clue about allocating 6 word registers
6793(define_expand "movstrsi_6reg"
b6c9286a
MM
6794 [(parallel [(set (match_operand 0 "" "")
6795 (match_operand 1 "" ""))
6796 (use (match_operand 2 "" ""))
6797 (use (match_operand 3 "" ""))
7e69e155
MM
6798 (clobber (reg:SI 7))
6799 (clobber (reg:SI 8))
6800 (clobber (reg:SI 9))
6801 (clobber (reg:SI 10))
6802 (clobber (reg:SI 11))
6803 (clobber (reg:SI 12))
3c67b673 6804 (clobber (match_scratch:SI 4 ""))])]
7e69e155
MM
6805 "TARGET_STRING"
6806 "")
6807
6808(define_insn ""
3c67b673
RK
6809 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6810 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6811 (use (match_operand:SI 2 "immediate_operand" "i"))
6812 (use (match_operand:SI 3 "immediate_operand" "i"))
6813 (clobber (match_operand:SI 4 "register_operand" "=r"))
7e69e155
MM
6814 (clobber (reg:SI 8))
6815 (clobber (reg:SI 9))
6816 (clobber (reg:SI 10))
6817 (clobber (reg:SI 11))
6818 (clobber (reg:SI 12))
3c67b673 6819 (clobber (match_scratch:SI 5 "=q"))]
7e69e155
MM
6820 "TARGET_STRING && TARGET_POWER
6821 && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24
6822 && (REGNO (operands[0]) < 7 || REGNO (operands[0]) > 12)
6823 && (REGNO (operands[1]) < 7 || REGNO (operands[1]) > 12)
3c67b673
RK
6824 && REGNO (operands[4]) == 7"
6825 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
b7ff3d82
DE
6826 [(set_attr "type" "load")
6827 (set_attr "length" "8")])
7e69e155
MM
6828
6829(define_insn ""
3c67b673
RK
6830 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6831 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6832 (use (match_operand:SI 2 "immediate_operand" "i"))
6833 (use (match_operand:SI 3 "immediate_operand" "i"))
6834 (clobber (match_operand:SI 4 "register_operand" "=r"))
7e69e155
MM
6835 (clobber (reg:SI 8))
6836 (clobber (reg:SI 9))
6837 (clobber (reg:SI 10))
6838 (clobber (reg:SI 11))
6839 (clobber (reg:SI 12))
3c67b673 6840 (clobber (match_scratch:SI 5 "X"))]
7e69e155
MM
6841 "TARGET_STRING && !TARGET_POWER
6842 && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
6843 && (REGNO (operands[0]) < 7 || REGNO (operands[0]) > 12)
6844 && (REGNO (operands[1]) < 7 || REGNO (operands[1]) > 12)
3c67b673
RK
6845 && REGNO (operands[4]) == 7"
6846 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
b7ff3d82
DE
6847 [(set_attr "type" "load")
6848 (set_attr "length" "8")])
7e69e155
MM
6849
6850;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill problems
6851;; with TImode
6852(define_expand "movstrsi_4reg"
b6c9286a
MM
6853 [(parallel [(set (match_operand 0 "" "")
6854 (match_operand 1 "" ""))
6855 (use (match_operand 2 "" ""))
6856 (use (match_operand 3 "" ""))
7e69e155
MM
6857 (clobber (reg:SI 9))
6858 (clobber (reg:SI 10))
6859 (clobber (reg:SI 11))
6860 (clobber (reg:SI 12))
3c67b673 6861 (clobber (match_scratch:SI 4 ""))])]
7e69e155
MM
6862 "TARGET_STRING"
6863 "")
6864
6865(define_insn ""
3c67b673
RK
6866 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6867 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6868 (use (match_operand:SI 2 "immediate_operand" "i"))
6869 (use (match_operand:SI 3 "immediate_operand" "i"))
6870 (clobber (match_operand:SI 4 "register_operand" "=r"))
7e69e155
MM
6871 (clobber (reg:SI 10))
6872 (clobber (reg:SI 11))
6873 (clobber (reg:SI 12))
3c67b673 6874 (clobber (match_scratch:SI 5 "=q"))]
7e69e155
MM
6875 "TARGET_STRING && TARGET_POWER
6876 && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
6877 && (REGNO (operands[0]) < 9 || REGNO (operands[0]) > 12)
6878 && (REGNO (operands[1]) < 9 || REGNO (operands[1]) > 12)
3c67b673
RK
6879 && REGNO (operands[4]) == 9"
6880 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
b7ff3d82
DE
6881 [(set_attr "type" "load")
6882 (set_attr "length" "8")])
7e69e155
MM
6883
6884(define_insn ""
3c67b673
RK
6885 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6886 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6887 (use (match_operand:SI 2 "immediate_operand" "i"))
6888 (use (match_operand:SI 3 "immediate_operand" "i"))
6889 (clobber (match_operand:SI 4 "register_operand" "=r"))
7e69e155
MM
6890 (clobber (reg:SI 10))
6891 (clobber (reg:SI 11))
6892 (clobber (reg:SI 12))
3c67b673 6893 (clobber (match_scratch:SI 5 "X"))]
7e69e155
MM
6894 "TARGET_STRING && !TARGET_POWER
6895 && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
6896 && (REGNO (operands[0]) < 9 || REGNO (operands[0]) > 12)
6897 && (REGNO (operands[1]) < 9 || REGNO (operands[1]) > 12)
3c67b673
RK
6898 && REGNO (operands[4]) == 9"
6899 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
b7ff3d82
DE
6900 [(set_attr "type" "load")
6901 (set_attr "length" "8")])
7e69e155
MM
6902
6903;; Move up to 8 bytes at a time.
6904(define_expand "movstrsi_2reg"
b6c9286a
MM
6905 [(parallel [(set (match_operand 0 "" "")
6906 (match_operand 1 "" ""))
6907 (use (match_operand 2 "" ""))
6908 (use (match_operand 3 "" ""))
3c67b673
RK
6909 (clobber (match_scratch:DI 4 ""))
6910 (clobber (match_scratch:SI 5 ""))])]
7e69e155
MM
6911 "TARGET_STRING && !TARGET_64BIT"
6912 "")
6913
6914(define_insn ""
3c67b673
RK
6915 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6916 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6917 (use (match_operand:SI 2 "immediate_operand" "i"))
6918 (use (match_operand:SI 3 "immediate_operand" "i"))
6919 (clobber (match_scratch:DI 4 "=&r"))
6920 (clobber (match_scratch:SI 5 "=q"))]
7e69e155 6921 "TARGET_STRING && TARGET_POWER && !TARGET_64BIT
3c67b673
RK
6922 && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
6923 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
b7ff3d82
DE
6924 [(set_attr "type" "load")
6925 (set_attr "length" "8")])
7e69e155
MM
6926
6927(define_insn ""
3c67b673
RK
6928 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6929 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6930 (use (match_operand:SI 2 "immediate_operand" "i"))
6931 (use (match_operand:SI 3 "immediate_operand" "i"))
6932 (clobber (match_scratch:DI 4 "=&r"))
6933 (clobber (match_scratch:SI 5 "X"))]
7e69e155
MM
6934 "TARGET_STRING && !TARGET_POWER && !TARGET_64BIT
6935 && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
3c67b673 6936 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
b7ff3d82
DE
6937 [(set_attr "type" "load")
6938 (set_attr "length" "8")])
7e69e155
MM
6939
6940;; Move up to 4 bytes at a time.
6941(define_expand "movstrsi_1reg"
b6c9286a
MM
6942 [(parallel [(set (match_operand 0 "" "")
6943 (match_operand 1 "" ""))
6944 (use (match_operand 2 "" ""))
6945 (use (match_operand 3 "" ""))
3c67b673
RK
6946 (clobber (match_scratch:SI 4 ""))
6947 (clobber (match_scratch:SI 5 ""))])]
7e69e155
MM
6948 "TARGET_STRING"
6949 "")
6950
6951(define_insn ""
3c67b673
RK
6952 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6953 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6954 (use (match_operand:SI 2 "immediate_operand" "i"))
6955 (use (match_operand:SI 3 "immediate_operand" "i"))
6956 (clobber (match_scratch:SI 4 "=&r"))
6957 (clobber (match_scratch:SI 5 "=q"))]
7e69e155
MM
6958 "TARGET_STRING && TARGET_POWER
6959 && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
3c67b673 6960 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
b7ff3d82
DE
6961 [(set_attr "type" "load")
6962 (set_attr "length" "8")])
7e69e155
MM
6963
6964(define_insn ""
3c67b673
RK
6965 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6966 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6967 (use (match_operand:SI 2 "immediate_operand" "i"))
6968 (use (match_operand:SI 3 "immediate_operand" "i"))
6969 (clobber (match_scratch:SI 4 "=&r"))
6970 (clobber (match_scratch:SI 5 "X"))]
7e69e155
MM
6971 "TARGET_STRING && !TARGET_POWER
6972 && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
3c67b673 6973 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
b7ff3d82
DE
6974 [(set_attr "type" "load")
6975 (set_attr "length" "8")])
7e69e155 6976
1fd4e8c1 6977\f
7e69e155 6978;; Define insns that do load or store with update. Some of these we can
1fd4e8c1
RK
6979;; get by using pre-decrement or pre-increment, but the hardware can also
6980;; do cases where the increment is not the size of the object.
6981;;
6982;; In all these cases, we use operands 0 and 1 for the register being
6983;; incremented because those are the operands that local-alloc will
6984;; tie and these are the pair most likely to be tieable (and the ones
6985;; that will benefit the most).
6986
38c1f2d7 6987(define_insn "*movdi_update1"
51b8fc2c 6988 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
ad8bd902 6989 (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
51b8fc2c
RK
6990 (match_operand:DI 2 "reg_or_short_operand" "r,I"))))
6991 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
6992 (plus:DI (match_dup 1) (match_dup 2)))]
38c1f2d7 6993 "TARGET_POWERPC64 && TARGET_UPDATE"
51b8fc2c
RK
6994 "@
6995 ldux %3,%0,%2
6996 ldu %3,%2(%0)"
6997 [(set_attr "type" "load")])
6998
38c1f2d7 6999(define_insn "*movdi_update2"
287f13ff
RK
7000 [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
7001 (sign_extend:DI
7002 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
7003 (match_operand:DI 2 "gpc_reg_operand" "r")))))
7004 (set (match_operand:DI 0 "gpc_reg_operand" "=b")
7005 (plus:DI (match_dup 1) (match_dup 2)))]
7006 "TARGET_POWERPC64"
7007 "lwaux %3,%0,%2"
7008 [(set_attr "type" "load")])
7009
4697a36c 7010(define_insn "movdi_update"
51b8fc2c
RK
7011 [(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
7012 (match_operand:DI 2 "reg_or_short_operand" "r,I")))
7013 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
7014 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
7015 (plus:DI (match_dup 1) (match_dup 2)))]
38c1f2d7 7016 "TARGET_POWERPC64 && TARGET_UPDATE"
51b8fc2c
RK
7017 "@
7018 stdux %3,%0,%2
b7ff3d82
DE
7019 stdu %3,%2(%0)"
7020 [(set_attr "type" "store")])
51b8fc2c 7021
38c1f2d7 7022(define_insn "*movsi_update1"
cd2b37d9
RK
7023 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
7024 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 7025 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
cd2b37d9 7026 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
7027 (plus:SI (match_dup 1) (match_dup 2)))]
7028 ""
7029 "@
ca7f5001
RK
7030 {lux|lwzux} %3,%0,%2
7031 {lu|lwzu} %3,%2(%0)"
cfb557c4 7032 [(set_attr "type" "load")])
1fd4e8c1 7033
4697a36c 7034(define_insn "movsi_update"
cd2b37d9 7035 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 7036 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
cd2b37d9
RK
7037 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
7038 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1 7039 (plus:SI (match_dup 1) (match_dup 2)))]
38c1f2d7 7040 "TARGET_UPDATE"
1fd4e8c1 7041 "@
ca7f5001 7042 {stux|stwux} %3,%0,%2
b7ff3d82
DE
7043 {stu|stwu} %3,%2(%0)"
7044 [(set_attr "type" "store")])
1fd4e8c1 7045
38c1f2d7 7046(define_insn "*movhi_update"
cd2b37d9
RK
7047 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
7048 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 7049 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
cd2b37d9 7050 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1 7051 (plus:SI (match_dup 1) (match_dup 2)))]
38c1f2d7 7052 "TARGET_UPDATE"
1fd4e8c1 7053 "@
5f243543
RK
7054 lhzux %3,%0,%2
7055 lhzu %3,%2(%0)"
cfb557c4 7056 [(set_attr "type" "load")])
1fd4e8c1 7057
38c1f2d7 7058(define_insn "*movhi_update2"
cd2b37d9 7059 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
1fd4e8c1 7060 (zero_extend:SI
cd2b37d9 7061 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 7062 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
cd2b37d9 7063 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1 7064 (plus:SI (match_dup 1) (match_dup 2)))]
38c1f2d7 7065 "TARGET_UPDATE"
1fd4e8c1 7066 "@
5f243543
RK
7067 lhzux %3,%0,%2
7068 lhzu %3,%2(%0)"
cfb557c4 7069 [(set_attr "type" "load")])
1fd4e8c1 7070
38c1f2d7 7071(define_insn "*movhi_update3"
cd2b37d9 7072 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
1fd4e8c1 7073 (sign_extend:SI
cd2b37d9 7074 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 7075 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
cd2b37d9 7076 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1 7077 (plus:SI (match_dup 1) (match_dup 2)))]
38c1f2d7 7078 "TARGET_UPDATE"
1fd4e8c1 7079 "@
5f243543
RK
7080 lhaux %3,%0,%2
7081 lhau %3,%2(%0)"
cfb557c4 7082 [(set_attr "type" "load")])
1fd4e8c1 7083
38c1f2d7 7084(define_insn "*movhi_update4"
cd2b37d9 7085 [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 7086 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
cd2b37d9
RK
7087 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
7088 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1 7089 (plus:SI (match_dup 1) (match_dup 2)))]
38c1f2d7 7090 "TARGET_UPDATE"
1fd4e8c1 7091 "@
5f243543 7092 sthux %3,%0,%2
b7ff3d82
DE
7093 sthu %3,%2(%0)"
7094 [(set_attr "type" "store")])
1fd4e8c1 7095
38c1f2d7 7096(define_insn "*movqi_update1"
cd2b37d9
RK
7097 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
7098 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 7099 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
cd2b37d9 7100 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1 7101 (plus:SI (match_dup 1) (match_dup 2)))]
38c1f2d7 7102 "TARGET_UPDATE"
1fd4e8c1 7103 "@
5f243543
RK
7104 lbzux %3,%0,%2
7105 lbzu %3,%2(%0)"
cfb557c4 7106 [(set_attr "type" "load")])
1fd4e8c1 7107
38c1f2d7 7108(define_insn "*movqi_update2"
cd2b37d9 7109 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
1fd4e8c1 7110 (zero_extend:SI
cd2b37d9 7111 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 7112 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
cd2b37d9 7113 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1 7114 (plus:SI (match_dup 1) (match_dup 2)))]
38c1f2d7 7115 "TARGET_UPDATE"
1fd4e8c1 7116 "@
5f243543
RK
7117 lbzux %3,%0,%2
7118 lbzu %3,%2(%0)"
cfb557c4 7119 [(set_attr "type" "load")])
1fd4e8c1 7120
38c1f2d7 7121(define_insn "*movqi_update3"
cd2b37d9 7122 [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 7123 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
cd2b37d9
RK
7124 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
7125 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1 7126 (plus:SI (match_dup 1) (match_dup 2)))]
38c1f2d7 7127 "TARGET_UPDATE"
1fd4e8c1 7128 "@
5f243543 7129 stbux %3,%0,%2
b7ff3d82
DE
7130 stbu %3,%2(%0)"
7131 [(set_attr "type" "store")])
1fd4e8c1 7132
38c1f2d7 7133(define_insn "*movsf_update1"
cd2b37d9 7134 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
df8b713c 7135 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 7136 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
cd2b37d9 7137 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1 7138 (plus:SI (match_dup 1) (match_dup 2)))]
38c1f2d7 7139 "TARGET_HARD_FLOAT && TARGET_UPDATE"
1fd4e8c1 7140 "@
5f243543
RK
7141 lfsux %3,%0,%2
7142 lfsu %3,%2(%0)"
cfb557c4 7143 [(set_attr "type" "fpload")])
1fd4e8c1 7144
38c1f2d7 7145(define_insn "*movsf_update2"
cd2b37d9 7146 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 7147 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
cd2b37d9
RK
7148 (match_operand:SF 3 "gpc_reg_operand" "f,f"))
7149 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1 7150 (plus:SI (match_dup 1) (match_dup 2)))]
38c1f2d7 7151 "TARGET_HARD_FLOAT && TARGET_UPDATE"
1fd4e8c1 7152 "@
85fff2f3 7153 stfsux %3,%0,%2
b7ff3d82
DE
7154 stfsu %3,%2(%0)"
7155 [(set_attr "type" "fpstore")])
1fd4e8c1 7156
38c1f2d7
MM
7157(define_insn "*movsf_update3"
7158 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
7159 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
7160 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
7161 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
7162 (plus:SI (match_dup 1) (match_dup 2)))]
7163 "TARGET_SOFT_FLOAT && TARGET_UPDATE"
7164 "@
7165 {lux|lwzux} %3,%0,%2
7166 {lu|lwzu} %3,%2(%0)"
7167 [(set_attr "type" "load")])
7168
7169(define_insn "*movsf_update4"
7170 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
7171 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
7172 (match_operand:SF 3 "gpc_reg_operand" "r,r"))
7173 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
7174 (plus:SI (match_dup 1) (match_dup 2)))]
7175 "TARGET_SOFT_FLOAT && TARGET_UPDATE"
7176 "@
7177 {stux|stwux} %3,%0,%2
7178 {stu|stwu} %3,%2(%0)"
7179 [(set_attr "type" "store")])
7180
7181(define_insn "*movdf_update1"
cd2b37d9
RK
7182 [(set (match_operand:DF 3 "gpc_reg_operand" "=f,f")
7183 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 7184 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
cd2b37d9 7185 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1 7186 (plus:SI (match_dup 1) (match_dup 2)))]
38c1f2d7 7187 "TARGET_HARD_FLOAT && TARGET_UPDATE"
1fd4e8c1 7188 "@
5f243543
RK
7189 lfdux %3,%0,%2
7190 lfdu %3,%2(%0)"
cfb557c4 7191 [(set_attr "type" "fpload")])
1fd4e8c1 7192
38c1f2d7 7193(define_insn "*movdf_update2"
cd2b37d9 7194 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 7195 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
cd2b37d9
RK
7196 (match_operand:DF 3 "gpc_reg_operand" "f,f"))
7197 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1 7198 (plus:SI (match_dup 1) (match_dup 2)))]
38c1f2d7 7199 "TARGET_HARD_FLOAT && TARGET_UPDATE"
1fd4e8c1 7200 "@
5f243543 7201 stfdux %3,%0,%2
b7ff3d82
DE
7202 stfdu %3,%2(%0)"
7203 [(set_attr "type" "fpstore")])
4c70a4f3
RK
7204
7205;; Peephole to convert two consecutive FP loads or stores into lfq/stfq.
7206
7207(define_peephole
7208 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
7209 (match_operand:DF 1 "memory_operand" ""))
7210 (set (match_operand:DF 2 "gpc_reg_operand" "=f")
7211 (match_operand:DF 3 "memory_operand" ""))]
7212 "TARGET_POWER2
d14a6d05 7213 && TARGET_HARD_FLOAT
4c70a4f3
RK
7214 && registers_ok_for_quad_peep (operands[0], operands[2])
7215 && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
7216 && addrs_ok_for_quad_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
7217 "lfq%U1%X1 %0,%1")
7218
7219(define_peephole
7220 [(set (match_operand:DF 0 "memory_operand" "")
7221 (match_operand:DF 1 "gpc_reg_operand" "f"))
7222 (set (match_operand:DF 2 "memory_operand" "")
7223 (match_operand:DF 3 "gpc_reg_operand" "f"))]
7224 "TARGET_POWER2
d14a6d05 7225 && TARGET_HARD_FLOAT
4c70a4f3
RK
7226 && registers_ok_for_quad_peep (operands[1], operands[3])
7227 && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
7228 && addrs_ok_for_quad_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
7229 "stfq%U0%X0 %1,%0")
1fd4e8c1
RK
7230\f
7231;; Next come insns related to the calling sequence.
7232;;
7233;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
7e69e155 7234;; We move the back-chain and decrement the stack pointer.
1fd4e8c1
RK
7235
7236(define_expand "allocate_stack"
a260abc9
DE
7237 [(set (match_operand 0 "register_operand" "=r")
7238 (minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
7239 (set (reg 1)
7240 (minus (reg 1) (match_dup 1)))]
1fd4e8c1
RK
7241 ""
7242 "
4697a36c 7243{ rtx chain = gen_reg_rtx (Pmode);
1fd4e8c1 7244 rtx stack_bot = gen_rtx (MEM, Pmode, stack_pointer_rtx);
4697a36c 7245 rtx neg_op0;
1fd4e8c1
RK
7246
7247 emit_move_insn (chain, stack_bot);
4697a36c 7248
e9a25f70
JL
7249 /* Under Windows NT, we need to add stack probes for large/variable
7250 allocations, so do it via a call to the external function alloca
7251 instead of doing it inline. */
979721f8 7252 if (DEFAULT_ABI == ABI_NT
e9a25f70 7253 && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) > 4096))
979721f8 7254 {
a260abc9 7255 rtx tmp = gen_reg_rtx (Pmode);
cea05fab 7256 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"__allocate_stack\"),
a260abc9 7257 tmp, 0, Pmode, 1, operands[1], Pmode);
cea05fab 7258 emit_insn (gen_set_sp (tmp));
e9a25f70 7259 emit_move_insn (operands[0], tmp);
979721f8
MM
7260 DONE;
7261 }
7262
e9a25f70
JL
7263 if (GET_CODE (operands[1]) != CONST_INT
7264 || INTVAL (operands[1]) < -32767
7265 || INTVAL (operands[1]) > 32768)
4697a36c
MM
7266 {
7267 neg_op0 = gen_reg_rtx (Pmode);
e6ca2c17 7268 if (TARGET_32BIT)
e9a25f70 7269 emit_insn (gen_negsi2 (neg_op0, operands[1]));
e6ca2c17 7270 else
e9a25f70 7271 emit_insn (gen_negdi2 (neg_op0, operands[1]));
4697a36c
MM
7272 }
7273 else
e9a25f70 7274 neg_op0 = GEN_INT (- INTVAL (operands[1]));
4697a36c 7275
38c1f2d7
MM
7276 if (TARGET_UPDATE)
7277 emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update : gen_movdi_update))
7278 (stack_pointer_rtx, stack_pointer_rtx, neg_op0, chain));
4697a36c 7279
38c1f2d7
MM
7280 else
7281 {
7282 emit_insn ((* ((TARGET_32BIT) ? gen_addsi3 : gen_adddi3))
7283 (stack_pointer_rtx, stack_pointer_rtx, neg_op0));
a260abc9 7284 emit_move_insn (gen_rtx (MEM, Pmode, stack_pointer_rtx), chain);
38c1f2d7 7285 }
e9a25f70
JL
7286
7287 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
1fd4e8c1
RK
7288 DONE;
7289}")
59257ff7 7290
cea05fab
MM
7291;; Marker to indicate that the stack pointer was changed under NT in
7292;; ways not known to the compiler
7293
7294(define_insn "set_sp"
7295 [(set (reg:SI 1)
7296 (unspec [(match_operand:SI 0 "register_operand" "r")] 7))]
7297 ""
7298 ""
7299 [(set_attr "length" "0")])
7300
59257ff7
RK
7301;; These patterns say how to save and restore the stack pointer. We need not
7302;; save the stack pointer at function level since we are careful to
7303;; preserve the backchain. At block level, we have to restore the backchain
7304;; when we restore the stack pointer.
7305;;
7306;; For nonlocal gotos, we must save both the stack pointer and its
7307;; backchain and restore both. Note that in the nonlocal case, the
7308;; save area is a memory location.
7309
7310(define_expand "save_stack_function"
7311 [(use (const_int 0))]
7312 ""
7313 "")
7314
7315(define_expand "restore_stack_function"
7316 [(use (const_int 0))]
7317 ""
7318 "")
7319
7320(define_expand "restore_stack_block"
a260abc9
DE
7321 [(set (match_dup 2) (mem (match_operand 0 "register_operand" "")))
7322 (set (match_dup 0) (match_operand 1 "register_operand" ""))
7323 (set (mem (match_dup 0)) (match_dup 2))]
59257ff7
RK
7324 ""
7325 "
a260abc9 7326{ operands[2] = gen_reg_rtx (Pmode); }")
59257ff7
RK
7327
7328(define_expand "save_stack_nonlocal"
a260abc9
DE
7329 [(match_operand 0 "memory_operand" "")
7330 (match_operand 1 "register_operand" "")]
59257ff7
RK
7331 ""
7332 "
7333{
a260abc9 7334 rtx temp = gen_reg_rtx (Pmode);
59257ff7
RK
7335
7336 /* Copy the backchain to the first word, sp to the second. */
a260abc9
DE
7337 emit_move_insn (temp, gen_rtx (MEM, Pmode, operands[1]));
7338 emit_move_insn (operand_subword (operands[0], 0, 0, (TARGET_32BIT ? DImode : TImode)),
7339 temp);
7340 emit_move_insn (operand_subword (operands[0], 1, 0, (TARGET_32BIT ? DImode : TImode)),
7341 operands[1]);
59257ff7
RK
7342 DONE;
7343}")
7e69e155 7344
59257ff7 7345(define_expand "restore_stack_nonlocal"
a260abc9
DE
7346 [(match_operand 0 "register_operand" "")
7347 (match_operand 1 "memory_operand" "")]
59257ff7
RK
7348 ""
7349 "
7350{
a260abc9 7351 rtx temp = gen_reg_rtx (Pmode);
59257ff7
RK
7352
7353 /* Restore the backchain from the first word, sp from the second. */
a260abc9
DE
7354 emit_move_insn (temp,
7355 operand_subword (operands[1], 0, 0, (TARGET_32BIT ? DImode : TImode)));
7356 emit_move_insn (operands[0],
7357 operand_subword (operands[1], 1, 0, (TARGET_32BIT ? DImode : TImode)));
7358 emit_move_insn (gen_rtx (MEM, Pmode, operands[0]), temp);
59257ff7
RK
7359 DONE;
7360}")
b6c9286a 7361
956d6950 7362;; If we have -mminimal-toc, we need to reload r30 after a nonlocal goto.
f0f6a223
RK
7363
7364(define_insn "nonlocal_goto_receiver"
7365 [(unspec_volatile [(const_int 0)] 1)]
e9a25f70 7366 "TARGET_TOC && TARGET_MINIMAL_TOC"
f0f6a223
RK
7367 "*
7368{
38c1f2d7 7369 rs6000_output_load_toc_table (asm_out_file, 30);
f0f6a223
RK
7370 return \"\";
7371}"
7372 [(set_attr "type" "load")])
b7ff3d82 7373\f
b6c9286a
MM
7374;; A function pointer under AIX is a pointer to a data area whose first word
7375;; contains the actual address of the function, whose second word contains a
7376;; pointer to its TOC, and whose third word contains a value to place in the
7377;; static chain register (r11). Note that if we load the static chain, our
1fd4e8c1
RK
7378;; "trampoline" need not have any executable code.
7379;;
b6c9286a
MM
7380;; operands[0] is a register pointing to the 3 word descriptor (aka, the function address)
7381;; operands[1] is the stack size to clean up
7382;; operands[2] is the value FUNCTION_ARG returns for the VOID argument (must be 0 for AIX)
7383;; operands[3] is location to store the TOC
7384;; operands[4] is the TOC register
7385;; operands[5] is the static chain register
7386;;
7387;; We do not break this into separate insns, so that the scheduler will not try
7388;; to move the load of the new TOC before any loads from the TOC.
7389
a260abc9 7390(define_insn "call_indirect_aix32"
b6c9286a
MM
7391 [(call (mem:SI (match_operand:SI 0 "register_operand" "b"))
7392 (match_operand 1 "const_int_operand" "n"))
6a4cee5f 7393 (use (match_operand 2 "const_int_operand" "n"))
b6c9286a
MM
7394 (use (match_operand 3 "offsettable_addr_operand" "p"))
7395 (use (match_operand 4 "register_operand" "r"))
7396 (clobber (match_operand 5 "register_operand" "=r"))
7397 (clobber (match_scratch:SI 6 "=&r"))
7398 (clobber (match_scratch:SI 7 "=l"))]
6a4cee5f
MM
7399 "DEFAULT_ABI == ABI_AIX
7400 && (INTVAL (operands[2]) == CALL_NORMAL || (INTVAL (operands[2]) & CALL_LONG) != 0)"
7401 "{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"
b7ff3d82
DE
7402 [(set_attr "type" "load")
7403 (set_attr "length" "28")])
b6c9286a 7404
a260abc9
DE
7405(define_insn "call_indirect_aix64"
7406 [(call (mem:SI (match_operand:DI 0 "register_operand" "b"))
7407 (match_operand 1 "const_int_operand" "n"))
7408 (use (match_operand 2 "const_int_operand" "n"))
7409 (use (match_operand 3 "offsettable_addr_operand" "p"))
7410 (use (match_operand 4 "register_operand" "r"))
7411 (clobber (match_operand 5 "register_operand" "=r"))
7412 (clobber (match_scratch:SI 6 "=&r"))
7413 (clobber (match_scratch:SI 7 "=l"))]
7414 "TARGET_64BIT && DEFAULT_ABI == ABI_AIX
7415 && (INTVAL (operands[2]) == CALL_NORMAL || (INTVAL (operands[2]) & CALL_LONG) != 0)"
7416 "stw %4,%a3\;ld %6,0(%0)\;ld %4,8(%0)\;mt%7 %6\;ld %5,16(%0)\;blrl\;ld %4,%a3"
7417 [(set_attr "type" "load")
7418 (set_attr "length" "28")])
7419
7420(define_insn "call_value_indirect_aix32"
b6c9286a
MM
7421 [(set (match_operand 0 "register_operand" "fg")
7422 (call (mem:SI (match_operand:SI 1 "register_operand" "b"))
7423 (match_operand 2 "const_int_operand" "n")))
6a4cee5f 7424 (use (match_operand 3 "const_int_operand" "n"))
b6c9286a
MM
7425 (use (match_operand 4 "offsettable_addr_operand" "p"))
7426 (use (match_operand 5 "register_operand" "r"))
7427 (clobber (match_operand 6 "register_operand" "=r"))
7428 (clobber (match_scratch:SI 7 "=&r"))
7429 (clobber (match_scratch:SI 8 "=l"))]
6a4cee5f
MM
7430 "DEFAULT_ABI == ABI_AIX
7431 && (INTVAL (operands[3]) == CALL_NORMAL || (INTVAL (operands[3]) & CALL_LONG) != 0)"
a260abc9
DE
7432 "{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"
7433 [(set_attr "type" "load")
7434 (set_attr "length" "28")])
7435
7436(define_insn "call_value_indirect_aix64"
7437 [(set (match_operand 0 "register_operand" "fg")
7438 (call (mem:SI (match_operand:DI 1 "register_operand" "b"))
7439 (match_operand 2 "const_int_operand" "n")))
7440 (use (match_operand 3 "const_int_operand" "n"))
7441 (use (match_operand 4 "offsettable_addr_operand" "p"))
7442 (use (match_operand 5 "register_operand" "r"))
7443 (clobber (match_operand 6 "register_operand" "=r"))
7444 (clobber (match_scratch:SI 7 "=&r"))
7445 (clobber (match_scratch:SI 8 "=l"))]
7446 "TARGET_64BIT && DEFAULT_ABI == ABI_AIX
7447 && (INTVAL (operands[3]) == CALL_NORMAL || (INTVAL (operands[3]) & CALL_LONG) != 0)"
7448 "stw %5,%a4\;ld %7,0(%1)\;ld %5,8(%1)\;mt%8 %7\;ld %6,16(%1)\;blrl\;ld %5,%a4"
b7ff3d82
DE
7449 [(set_attr "type" "load")
7450 (set_attr "length" "28")])
b6c9286a
MM
7451
7452;; A function pointer undef NT is a pointer to a data area whose first word
7453;; contains the actual address of the function, whose second word contains a
7454;; pointer to its TOC. The static chain is not stored under NT, which means
7455;; that we need a trampoline.
7456;;
7457;; operands[0] is an SImode pseudo in which we place the address of the function.
7458;; operands[1] is the stack size to clean up
7459;; operands[2] is the value FUNCTION_ARG returns for the VOID argument (must be 0 for NT)
7460;; operands[3] is location to store the TOC
7461;; operands[4] is the TOC register
7462;;
7463;; We do not break this into separate insns, so that the scheduler will not try
7464;; to move the load of the new TOC before any loads from the TOC.
7465
7466(define_insn "call_indirect_nt"
7467 [(call (mem:SI (match_operand:SI 0 "register_operand" "b"))
7468 (match_operand 1 "const_int_operand" "n"))
6a4cee5f 7469 (use (match_operand 2 "const_int_operand" "n"))
b6c9286a
MM
7470 (use (match_operand 3 "offsettable_addr_operand" "p"))
7471 (use (match_operand 4 "register_operand" "r"))
7472 (clobber (match_scratch:SI 5 "=&r"))
7473 (clobber (match_scratch:SI 6 "=l"))]
6a4cee5f
MM
7474 "DEFAULT_ABI == ABI_NT
7475 && (INTVAL (operands[2]) == CALL_NORMAL || (INTVAL (operands[2]) & CALL_LONG) != 0)"
e1f83b4d 7476 "{st|stw} %4,%a3\;{l|lwz} %5,0(%0)\;{l|lwz} %4,4(%0)\;mt%6 %5\;{brl|blrl}\;{l|lwz} %4,%a3"
b7ff3d82
DE
7477 [(set_attr "type" "load")
7478 (set_attr "length" "24")])
b6c9286a
MM
7479
7480(define_insn "call_value_indirect_nt"
7481 [(set (match_operand 0 "register_operand" "fg")
7482 (call (mem:SI (match_operand:SI 1 "register_operand" "b"))
7483 (match_operand 2 "const_int_operand" "n")))
6a4cee5f 7484 (use (match_operand 3 "const_int_operand" "n"))
b6c9286a
MM
7485 (use (match_operand 4 "offsettable_addr_operand" "p"))
7486 (use (match_operand 5 "register_operand" "r"))
7487 (clobber (match_scratch:SI 6 "=&r"))
7488 (clobber (match_scratch:SI 7 "=l"))]
6a4cee5f
MM
7489 "DEFAULT_ABI == ABI_NT
7490 && (INTVAL (operands[3]) == CALL_NORMAL || (INTVAL (operands[3]) & CALL_LONG) != 0)"
e1f83b4d 7491 "{st|stw} %5,%a4\;{l|lwz} %6,0(%1)\;{l|lwz} %5,4(%1)\;mt%7 %6\;{brl|blrl}\;{l|lwz} %5,%a4"
b7ff3d82
DE
7492 [(set_attr "type" "load")
7493 (set_attr "length" "24")])
b6c9286a
MM
7494
7495;; A function pointer under System V is just a normal pointer
7496;; operands[0] is the function pointer
7497;; operands[1] is the stack size to clean up
7498;; operands[2] is the value FUNCTION_ARG returns for the VOID argument which indicates how to set cr1
7499
7500(define_insn "call_indirect_sysv"
7501 [(call (mem:SI (match_operand:SI 0 "register_operand" "l,l"))
7502 (match_operand 1 "const_int_operand" "n,n"))
7503 (use (match_operand 2 "const_int_operand" "O,n"))
7504 (clobber (match_scratch:SI 3 "=l,l"))]
c81bebd7 7505 "DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS || DEFAULT_ABI == ABI_AIX_NODESC"
b6c9286a
MM
7506 "*
7507{
6a4cee5f
MM
7508 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
7509 output_asm_insn (\"crxor 6,6,6\", operands);
1fd4e8c1 7510
6a4cee5f
MM
7511 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
7512 output_asm_insn (\"creqv 6,6,6\", operands);
b6c9286a
MM
7513
7514 return \"{brl|blrl}\";
7515}"
b7ff3d82
DE
7516 [(set_attr "type" "jmpreg")
7517 (set_attr "length" "4,8")])
b6c9286a
MM
7518
7519(define_insn "call_value_indirect_sysv"
7520 [(set (match_operand 0 "register_operand" "=fg,fg")
7521 (call (mem:SI (match_operand:SI 1 "register_operand" "l,l"))
7522 (match_operand 2 "const_int_operand" "n,n")))
7523 (use (match_operand 3 "const_int_operand" "O,n"))
7524 (clobber (match_scratch:SI 4 "=l,l"))]
c81bebd7 7525 "DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS || DEFAULT_ABI == ABI_AIX_NODESC"
b6c9286a
MM
7526 "*
7527{
6a4cee5f
MM
7528 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
7529 output_asm_insn (\"crxor 6,6,6\", operands);
b6c9286a 7530
6a4cee5f
MM
7531 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
7532 output_asm_insn (\"creqv 6,6,6\", operands);
b6c9286a
MM
7533
7534 return \"{brl|blrl}\";
7535}"
b7ff3d82
DE
7536 [(set_attr "type" "jmpreg")
7537 (set_attr "length" "4,8")])
1fd4e8c1 7538
b6c9286a 7539;; Now the definitions for the call and call_value insns
1fd4e8c1 7540(define_expand "call"
a260abc9 7541 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
1fd4e8c1 7542 (match_operand 1 "" ""))
4697a36c 7543 (use (match_operand 2 "" ""))
1fd4e8c1
RK
7544 (clobber (scratch:SI))])]
7545 ""
7546 "
7547{
7548 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != CONST_INT)
7549 abort ();
7550
7551 operands[0] = XEXP (operands[0], 0);
7509c759
MM
7552
7553 /* Convert NT DLL imports into an indirect call. */
7554 if (GET_CODE (operands[0]) == SYMBOL_REF
6a4cee5f 7555 && (INTVAL (operands[2]) & CALL_NT_DLLIMPORT) != 0)
7509c759
MM
7556 {
7557 operands[0] = rs6000_dll_import_ref (operands[0]);
7558 operands[2] = GEN_INT ((int)CALL_NORMAL);
7559 }
7560
6a4cee5f
MM
7561 if (GET_CODE (operands[0]) != SYMBOL_REF
7562 || (INTVAL (operands[2]) & CALL_LONG) != 0)
1fd4e8c1 7563 {
6a4cee5f
MM
7564 if (INTVAL (operands[2]) & CALL_LONG)
7565 operands[0] = rs6000_longcall_ref (operands[0]);
7566
c81bebd7 7567 if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_SOLARIS)
b6c9286a
MM
7568 emit_call_insn (gen_call_indirect_sysv (force_reg (Pmode, operands[0]),
7569 operands[1], operands[2]));
7570 else
7571 {
7572 rtx toc_reg = gen_rtx (REG, Pmode, 2);
7573 rtx toc_addr = RS6000_SAVE_TOC;
1fd4e8c1 7574
b6c9286a
MM
7575 if (DEFAULT_ABI == ABI_AIX)
7576 {
7577 /* AIX function pointers are really pointers to a three word area */
7578 rtx static_chain = gen_rtx (REG, Pmode, STATIC_CHAIN_REGNUM);
a260abc9
DE
7579 emit_call_insn (TARGET_32BIT
7580 ? gen_call_indirect_aix32 (force_reg (Pmode, operands[0]),
7581 operands[1], operands[2],
7582 toc_addr, toc_reg, static_chain)
7583 : gen_call_indirect_aix64 (force_reg (Pmode, operands[0]),
7584 operands[1], operands[2],
7585 toc_addr, toc_reg, static_chain));
b6c9286a
MM
7586 }
7587 else if (DEFAULT_ABI == ABI_NT)
7588 {
7589 /* NT function pointers are really pointers to a two word area */
7590 emit_call_insn (gen_call_indirect_nt (force_reg (Pmode, operands[0]),
7591 operands[1], operands[2],
7592 toc_addr, toc_reg));
7593 }
7594 else
7595 abort ();
7596 }
7597 DONE;
1fd4e8c1
RK
7598 }
7599}")
7600
7601(define_expand "call_value"
7602 [(parallel [(set (match_operand 0 "" "")
a260abc9 7603 (call (mem:SI (match_operand 1 "address_operand" ""))
1fd4e8c1 7604 (match_operand 2 "" "")))
4697a36c 7605 (use (match_operand 3 "" ""))
1fd4e8c1
RK
7606 (clobber (scratch:SI))])]
7607 ""
7608 "
7609{
7610 if (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != CONST_INT)
7611 abort ();
7612
7613 operands[1] = XEXP (operands[1], 0);
7509c759
MM
7614
7615 /* Convert NT DLL imports into an indirect call. */
7616 if (GET_CODE (operands[1]) == SYMBOL_REF
6a4cee5f 7617 && (INTVAL (operands[3]) & CALL_NT_DLLIMPORT) != 0)
7509c759
MM
7618 {
7619 operands[1] = rs6000_dll_import_ref (operands[1]);
7620 operands[3] = GEN_INT ((int)CALL_NORMAL);
7621 }
7622
6a4cee5f
MM
7623 if (GET_CODE (operands[1]) != SYMBOL_REF
7624 || (INTVAL (operands[3]) & CALL_LONG) != 0)
1fd4e8c1 7625 {
6a4cee5f
MM
7626 if (INTVAL (operands[2]) & CALL_LONG)
7627 operands[1] = rs6000_longcall_ref (operands[1]);
7628
c81bebd7 7629 if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_SOLARIS)
b6c9286a
MM
7630 emit_call_insn (gen_call_value_indirect_sysv (operands[0], operands[1],
7631 operands[2], operands[3]));
7632 else
7633 {
7634 rtx toc_reg = gen_rtx (REG, Pmode, 2);
7635 rtx toc_addr = RS6000_SAVE_TOC;
1fd4e8c1 7636
b6c9286a
MM
7637 if (DEFAULT_ABI == ABI_AIX)
7638 {
7639 /* AIX function pointers are really pointers to a three word area */
7640 rtx static_chain = gen_rtx (REG, Pmode, STATIC_CHAIN_REGNUM);
a260abc9
DE
7641 emit_call_insn (TARGET_32BIT
7642 ? gen_call_value_indirect_aix32 (operands[0],
7643 force_reg (Pmode, operands[1]),
7644 operands[2], operands[3],
7645 toc_addr, toc_reg, static_chain)
7646 : gen_call_value_indirect_aix64 (operands[0],
7647 force_reg (Pmode, operands[1]),
7648 operands[2], operands[3],
7649 toc_addr, toc_reg, static_chain));
b6c9286a
MM
7650 }
7651 else if (DEFAULT_ABI == ABI_NT)
7652 {
7653 /* NT function pointers are really pointers to a two word area */
7654 emit_call_insn (gen_call_value_indirect_nt (operands[0],
7655 force_reg (Pmode, operands[1]),
7656 operands[2], operands[3],
7657 toc_addr, toc_reg));
7658 }
7659 else
7660 abort ();
7661 }
7662 DONE;
1fd4e8c1
RK
7663 }
7664}")
7665
04780ee7 7666;; Call to function in current module. No TOC pointer reload needed.
4697a36c
MM
7667;; Operand2 is non-zero if we are using the V.4 calling sequence and
7668;; either the function was not prototyped, or it was prototyped as a
7669;; variable argument function. It is > 0 if FP registers were passed
7670;; and < 0 if they were not.
04780ee7 7671
a260abc9 7672(define_insn "*call_local32"
4697a36c
MM
7673 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
7674 (match_operand 1 "" "g,g"))
7675 (use (match_operand:SI 2 "immediate_operand" "O,n"))
7676 (clobber (match_scratch:SI 3 "=l,l"))]
5a19791c 7677 "(INTVAL (operands[2]) & CALL_LONG) == 0"
4697a36c
MM
7678 "*
7679{
6a4cee5f
MM
7680 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
7681 output_asm_insn (\"crxor 6,6,6\", operands);
7682
7683 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
7684 output_asm_insn (\"creqv 6,6,6\", operands);
4697a36c 7685
a226df46 7686 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
4697a36c 7687}"
b7ff3d82
DE
7688 [(set_attr "type" "branch")
7689 (set_attr "length" "4,8")])
04780ee7 7690
a260abc9
DE
7691(define_insn "*call_local64"
7692 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
7693 (match_operand 1 "" "g,g"))
7694 (use (match_operand:SI 2 "immediate_operand" "O,n"))
7695 (clobber (match_scratch:SI 3 "=l,l"))]
7696 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
7697 "*
7698{
7699 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
7700 output_asm_insn (\"crxor 6,6,6\", operands);
7701
7702 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
7703 output_asm_insn (\"creqv 6,6,6\", operands);
7704
7705 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
7706}"
7707 [(set_attr "type" "branch")
7708 (set_attr "length" "4,8")])
7709
7710(define_insn "*ret_call_local32"
7711 [(set (match_operand 0 "" "=fg,fg")
7712 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
7713 (match_operand 2 "" "g,g")))
7714 (use (match_operand:SI 3 "immediate_operand" "O,n"))
7715 (clobber (match_scratch:SI 4 "=l,l"))]
7716 "(INTVAL (operands[3]) & CALL_LONG) == 0"
7717 "*
7718{
7719 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
7720 output_asm_insn (\"crxor 6,6,6\", operands);
7721
7722 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
7723 output_asm_insn (\"creqv 6,6,6\", operands);
7724
7725 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
7726}"
7727 [(set_attr "type" "branch")
7728 (set_attr "length" "4,8")])
7729
7730
7731(define_insn "*ret_call_local64"
7732 [(set (match_operand 0 "" "=fg,fg")
7733 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
7734 (match_operand 2 "" "g,g")))
7735 (use (match_operand:SI 3 "immediate_operand" "O,n"))
7736 (clobber (match_scratch:SI 4 "=l,l"))]
7737 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
7738 "*
7739{
7740 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
7741 output_asm_insn (\"crxor 6,6,6\", operands);
7742
7743 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
7744 output_asm_insn (\"creqv 6,6,6\", operands);
7745
7746 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
7747}"
7748 [(set_attr "type" "branch")
7749 (set_attr "length" "4,8")])
7750
04780ee7 7751;; Call to function which may be in another module. Restore the TOC
911f679c 7752;; pointer (r2) after the call unless this is System V.
4697a36c
MM
7753;; Operand2 is non-zero if we are using the V.4 calling sequence and
7754;; either the function was not prototyped, or it was prototyped as a
7755;; variable argument function. It is > 0 if FP registers were passed
7756;; and < 0 if they were not.
04780ee7 7757
a260abc9 7758(define_insn "*call_nonlocal_aix32"
b6c9286a
MM
7759 [(call (mem:SI (match_operand:SI 0 "call_operand" "s,s"))
7760 (match_operand 1 "" "fg,fg"))
7761 (use (match_operand:SI 2 "immediate_operand" "O,n"))
7762 (clobber (match_scratch:SI 3 "=l,l"))]
6a4cee5f 7763 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
5a19791c 7764 && (INTVAL (operands[2]) & CALL_LONG) == 0"
911f679c
MM
7765 "*
7766{
b6c9286a 7767 /* Indirect calls should go through call_indirect */
0f07e76c 7768 if (GET_CODE (operands[0]) == REG)
b6c9286a 7769 abort ();
911f679c 7770
6a4cee5f
MM
7771 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
7772 output_asm_insn (\"crxor 6,6,6\", operands);
7773
7774 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
7775 output_asm_insn (\"creqv 6,6,6\", operands);
7509c759 7776
b6c9286a
MM
7777 return (TARGET_WINDOWS_NT) ? \"bl %z0\;.znop %z0\" : \"bl %z0\;%.\";
7778}"
b7ff3d82
DE
7779 [(set_attr "type" "branch")
7780 (set_attr "length" "8,12")])
59313e4e 7781
a260abc9
DE
7782(define_insn "*call_nonlocal_aix64"
7783 [(call (mem:SI (match_operand:DI 0 "call_operand" "s,s"))
7784 (match_operand 1 "" "fg,fg"))
7785 (use (match_operand:SI 2 "immediate_operand" "O,n"))
7786 (clobber (match_scratch:SI 3 "=l,l"))]
7787 "TARGET_64BIT && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
7788 && (INTVAL (operands[2]) & CALL_LONG) == 0"
7789 "*
7790{
7791 /* Indirect calls should go through call_indirect */
7792 if (GET_CODE (operands[0]) == REG)
7793 abort ();
7794
7795 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
7796 output_asm_insn (\"crxor 6,6,6\", operands);
7797
7798 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
7799 output_asm_insn (\"creqv 6,6,6\", operands);
7800
7801 return (TARGET_WINDOWS_NT) ? \"bl %z0\;.znop %z0\" : \"bl %z0\;%.\";
7802}"
7803 [(set_attr "type" "branch")
7804 (set_attr "length" "8,12")])
7805
7806(define_insn "*call_nonlocal_sysv"
b6c9286a
MM
7807 [(call (mem:SI (match_operand:SI 0 "call_operand" "s,s"))
7808 (match_operand 1 "" "fg,fg"))
7809 (use (match_operand:SI 2 "immediate_operand" "O,n"))
7810 (clobber (match_scratch:SI 3 "=l,l"))]
c81bebd7 7811 "(DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
5a19791c 7812 && (INTVAL (operands[2]) & CALL_LONG) == 0"
b6c9286a
MM
7813 "*
7814{
b6c9286a 7815 /* Indirect calls should go through call_indirect */
0f07e76c 7816 if (GET_CODE (operands[0]) == REG)
b6c9286a 7817 abort ();
59313e4e 7818
6a4cee5f
MM
7819 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
7820 output_asm_insn (\"crxor 6,6,6\", operands);
7821
7822 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
7823 output_asm_insn (\"creqv 6,6,6\", operands);
7509c759 7824
a226df46 7825 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@plt\" : \"bl %z0\";
911f679c 7826}"
b7ff3d82
DE
7827 [(set_attr "type" "branch")
7828 (set_attr "length" "4,8")])
1fd4e8c1 7829
a260abc9 7830(define_insn "*ret_call_nonlocal_aix32"
4697a36c 7831 [(set (match_operand 0 "" "=fg,fg")
a260abc9
DE
7832 (call (mem:SI (match_operand:SI 1 "call_operand" "s,s"))
7833 (match_operand 2 "" "fg,fg")))
4697a36c
MM
7834 (use (match_operand:SI 3 "immediate_operand" "O,n"))
7835 (clobber (match_scratch:SI 4 "=l,l"))]
a260abc9
DE
7836 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
7837 && (INTVAL (operands[3]) & CALL_LONG) == 0"
4697a36c
MM
7838 "*
7839{
a260abc9
DE
7840 /* This should be handled by call_value_indirect */
7841 if (GET_CODE (operands[1]) == REG)
7842 abort ();
7843
6a4cee5f
MM
7844 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
7845 output_asm_insn (\"crxor 6,6,6\", operands);
7846
7847 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
7848 output_asm_insn (\"creqv 6,6,6\", operands);
4697a36c 7849
a260abc9 7850 return (TARGET_WINDOWS_NT) ? \"bl %z1\;.znop %z1\" : \"bl %z1\;%.\";
4697a36c 7851}"
b7ff3d82 7852 [(set_attr "type" "branch")
a260abc9 7853 (set_attr "length" "8,12")])
04780ee7 7854
a260abc9 7855(define_insn "*ret_call_nonlocal_aix64"
b6c9286a 7856 [(set (match_operand 0 "" "=fg,fg")
a260abc9 7857 (call (mem:SI (match_operand:DI 1 "call_operand" "s,s"))
b6c9286a
MM
7858 (match_operand 2 "" "fg,fg")))
7859 (use (match_operand:SI 3 "immediate_operand" "O,n"))
7860 (clobber (match_scratch:SI 4 "=l,l"))]
a260abc9 7861 "TARGET_64BIT && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
5a19791c 7862 && (INTVAL (operands[3]) & CALL_LONG) == 0"
911f679c
MM
7863 "*
7864{
b6c9286a 7865 /* This should be handled by call_value_indirect */
59313e4e 7866 if (GET_CODE (operands[1]) == REG)
b6c9286a
MM
7867 abort ();
7868
6a4cee5f
MM
7869 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
7870 output_asm_insn (\"crxor 6,6,6\", operands);
7871
7872 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
7873 output_asm_insn (\"creqv 6,6,6\", operands);
7509c759 7874
b6c9286a
MM
7875 return (TARGET_WINDOWS_NT) ? \"bl %z1\;.znop %z1\" : \"bl %z1\;%.\";
7876}"
b7ff3d82
DE
7877 [(set_attr "type" "branch")
7878 (set_attr "length" "8,12")])
b6c9286a 7879
a260abc9 7880(define_insn "*ret_call_nonlocal_sysv"
b6c9286a
MM
7881 [(set (match_operand 0 "" "=fg,fg")
7882 (call (mem:SI (match_operand:SI 1 "call_operand" "s,s"))
7883 (match_operand 2 "" "fg,fg")))
7884 (use (match_operand:SI 3 "immediate_operand" "O,n"))
7885 (clobber (match_scratch:SI 4 "=l,l"))]
c81bebd7 7886 "(DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
5a19791c 7887 && (INTVAL (operands[3]) & CALL_LONG) == 0"
b6c9286a
MM
7888 "*
7889{
b6c9286a 7890 /* This should be handled by call_value_indirect */
59313e4e 7891 if (GET_CODE (operands[1]) == REG)
b6c9286a 7892 abort ();
59313e4e 7893
6a4cee5f
MM
7894 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
7895 output_asm_insn (\"crxor 6,6,6\", operands);
7896
7897 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
7898 output_asm_insn (\"creqv 6,6,6\", operands);
7509c759 7899
a226df46 7900 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@plt\" : \"bl %z1\";
911f679c 7901}"
b7ff3d82
DE
7902 [(set_attr "type" "branch")
7903 (set_attr "length" "4,8")])
e6f948e3
RK
7904
7905;; Call subroutine returning any type.
e6f948e3
RK
7906(define_expand "untyped_call"
7907 [(parallel [(call (match_operand 0 "" "")
7908 (const_int 0))
7909 (match_operand 1 "" "")
7910 (match_operand 2 "" "")])]
7911 ""
7912 "
7913{
7914 int i;
7915
4697a36c 7916 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx, const0_rtx));
e6f948e3
RK
7917
7918 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7919 {
7920 rtx set = XVECEXP (operands[2], 0, i);
7921 emit_move_insn (SET_DEST (set), SET_SRC (set));
7922 }
7923
7924 /* The optimizer does not know that the call sets the function value
7925 registers we stored in the result block. We avoid problems by
7926 claiming that all hard registers are used and clobbered at this
7927 point. */
7928 emit_insn (gen_blockage ());
7929
7930 DONE;
7931}")
7932
7933;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7934;; all of memory. This blocks insns from being moved across this point.
7935
7936(define_insn "blockage"
7937 [(unspec_volatile [(const_int 0)] 0)]
7938 ""
7939 "")
4697a36c 7940
766a866c
MM
7941;; V.4 specific code to initialize the PIC register
7942
7943(define_insn "init_v4_pic"
7944 [(set (match_operand:SI 0 "register_operand" "=l")
7945 (unspec [(const_int 0)] 7))]
c81bebd7 7946 "DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS"
eaf1bcf1 7947 "bl _GLOBAL_OFFSET_TABLE_@local-4"
63d7d7a1
MM
7948 [(set_attr "type" "branch")
7949 (set_attr "length" "4")])
766a866c 7950
1fd4e8c1
RK
7951\f
7952;; Compare insns are next. Note that the RS/6000 has two types of compares,
7e69e155 7953;; signed & unsigned, and one type of branch.
1fd4e8c1
RK
7954;;
7955;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
7956;; insns, and branches. We store the operands of compares until we see
7957;; how it is used.
7958(define_expand "cmpsi"
7959 [(set (cc0)
cd2b37d9 7960 (compare (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7961 (match_operand:SI 1 "reg_or_short_operand" "")))]
7962 ""
7963 "
7964{
7965 /* Take care of the possibility that operands[1] might be negative but
7966 this might be a logical operation. That insn doesn't exist. */
7967 if (GET_CODE (operands[1]) == CONST_INT
7968 && INTVAL (operands[1]) < 0)
7969 operands[1] = force_reg (SImode, operands[1]);
7970
7971 rs6000_compare_op0 = operands[0];
7972 rs6000_compare_op1 = operands[1];
7973 rs6000_compare_fp_p = 0;
7974 DONE;
7975}")
7976
266eb58a
DE
7977(define_expand "cmpdi"
7978 [(set (cc0)
7979 (compare (match_operand:DI 0 "gpc_reg_operand" "")
7980 (match_operand:DI 1 "reg_or_short_operand" "")))]
7981 "TARGET_POWERPC64"
7982 "
7983{
7984 /* Take care of the possibility that operands[1] might be negative but
7985 this might be a logical operation. That insn doesn't exist. */
7986 if (GET_CODE (operands[1]) == CONST_INT
7987 && INTVAL (operands[1]) < 0)
7988 operands[1] = force_reg (DImode, operands[1]);
7989
7990 rs6000_compare_op0 = operands[0];
7991 rs6000_compare_op1 = operands[1];
7992 rs6000_compare_fp_p = 0;
7993 DONE;
7994}")
7995
1fd4e8c1 7996(define_expand "cmpsf"
cd2b37d9
RK
7997 [(set (cc0) (compare (match_operand:SF 0 "gpc_reg_operand" "")
7998 (match_operand:SF 1 "gpc_reg_operand" "")))]
d14a6d05 7999 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
8000 "
8001{
8002 rs6000_compare_op0 = operands[0];
8003 rs6000_compare_op1 = operands[1];
8004 rs6000_compare_fp_p = 1;
8005 DONE;
8006}")
8007
8008(define_expand "cmpdf"
cd2b37d9
RK
8009 [(set (cc0) (compare (match_operand:DF 0 "gpc_reg_operand" "")
8010 (match_operand:DF 1 "gpc_reg_operand" "")))]
d14a6d05 8011 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
8012 "
8013{
8014 rs6000_compare_op0 = operands[0];
8015 rs6000_compare_op1 = operands[1];
8016 rs6000_compare_fp_p = 1;
8017 DONE;
8018}")
8019
8020(define_expand "beq"
8021 [(set (match_dup 2) (match_dup 1))
8022 (set (pc)
8023 (if_then_else (eq (match_dup 2)
8024 (const_int 0))
8025 (label_ref (match_operand 0 "" ""))
8026 (pc)))]
8027 ""
8028 "
8029{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
8030 operands[1] = gen_rtx (COMPARE, mode,
8031 rs6000_compare_op0, rs6000_compare_op1);
8032 operands[2] = gen_reg_rtx (mode);
8033}")
8034
8035(define_expand "bne"
8036 [(set (match_dup 2) (match_dup 1))
8037 (set (pc)
8038 (if_then_else (ne (match_dup 2)
8039 (const_int 0))
8040 (label_ref (match_operand 0 "" ""))
8041 (pc)))]
8042 ""
8043 "
8044{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
8045 operands[1] = gen_rtx (COMPARE, mode,
8046 rs6000_compare_op0, rs6000_compare_op1);
8047 operands[2] = gen_reg_rtx (mode);
8048}")
8049
8050(define_expand "blt"
8051 [(set (match_dup 2) (match_dup 1))
8052 (set (pc)
8053 (if_then_else (lt (match_dup 2)
8054 (const_int 0))
8055 (label_ref (match_operand 0 "" ""))
8056 (pc)))]
8057 ""
8058 "
8059{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
8060 operands[1] = gen_rtx (COMPARE, mode,
8061 rs6000_compare_op0, rs6000_compare_op1);
8062 operands[2] = gen_reg_rtx (mode);
8063}")
8064
8065(define_expand "bgt"
8066 [(set (match_dup 2) (match_dup 1))
8067 (set (pc)
8068 (if_then_else (gt (match_dup 2)
8069 (const_int 0))
8070 (label_ref (match_operand 0 "" ""))
8071 (pc)))]
8072 ""
8073 "
8074{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
8075 operands[1] = gen_rtx (COMPARE, mode,
8076 rs6000_compare_op0, rs6000_compare_op1);
8077 operands[2] = gen_reg_rtx (mode);
8078}")
8079
8080(define_expand "ble"
8081 [(set (match_dup 2) (match_dup 1))
8082 (set (pc)
8083 (if_then_else (le (match_dup 2)
8084 (const_int 0))
8085 (label_ref (match_operand 0 "" ""))
8086 (pc)))]
8087 ""
8088 "
8089{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
8090 operands[1] = gen_rtx (COMPARE, mode,
8091 rs6000_compare_op0, rs6000_compare_op1);
8092 operands[2] = gen_reg_rtx (mode);
8093}")
8094
8095(define_expand "bge"
8096 [(set (match_dup 2) (match_dup 1))
8097 (set (pc)
8098 (if_then_else (ge (match_dup 2)
8099 (const_int 0))
8100 (label_ref (match_operand 0 "" ""))
8101 (pc)))]
8102 ""
8103 "
8104{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
8105 operands[1] = gen_rtx (COMPARE, mode,
8106 rs6000_compare_op0, rs6000_compare_op1);
8107 operands[2] = gen_reg_rtx (mode);
8108}")
8109
8110(define_expand "bgtu"
8111 [(set (match_dup 2) (match_dup 1))
8112 (set (pc)
8113 (if_then_else (gtu (match_dup 2)
8114 (const_int 0))
8115 (label_ref (match_operand 0 "" ""))
8116 (pc)))]
8117 ""
8118 "
8119{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
8120 rs6000_compare_op0, rs6000_compare_op1);
8121 operands[2] = gen_reg_rtx (CCUNSmode);
8122}")
8123
8124(define_expand "bltu"
8125 [(set (match_dup 2) (match_dup 1))
8126 (set (pc)
8127 (if_then_else (ltu (match_dup 2)
8128 (const_int 0))
8129 (label_ref (match_operand 0 "" ""))
8130 (pc)))]
8131 ""
8132 "
8133{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
8134 rs6000_compare_op0, rs6000_compare_op1);
8135 operands[2] = gen_reg_rtx (CCUNSmode);
8136}")
8137
8138(define_expand "bgeu"
8139 [(set (match_dup 2) (match_dup 1))
8140 (set (pc)
8141 (if_then_else (geu (match_dup 2)
8142 (const_int 0))
8143 (label_ref (match_operand 0 "" ""))
8144 (pc)))]
8145 ""
8146 "
8147{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
8148 rs6000_compare_op0, rs6000_compare_op1);
8149 operands[2] = gen_reg_rtx (CCUNSmode);
8150}")
8151
8152(define_expand "bleu"
8153 [(set (match_dup 2) (match_dup 1))
8154 (set (pc)
8155 (if_then_else (leu (match_dup 2)
8156 (const_int 0))
8157 (label_ref (match_operand 0 "" ""))
8158 (pc)))]
8159 ""
8160 "
8161{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
8162 rs6000_compare_op0, rs6000_compare_op1);
8163 operands[2] = gen_reg_rtx (CCUNSmode);
8164}")
8165
8166;; For SNE, we would prefer that the xor/abs sequence be used for integers.
8167;; For SEQ, likewise, except that comparisons with zero should be done
8168;; with an scc insns. However, due to the order that combine see the
8169;; resulting insns, we must, in fact, allow SEQ for integers. Fail in
8170;; the cases we don't want to handle.
8171(define_expand "seq"
8172 [(set (match_dup 2) (match_dup 1))
cd2b37d9 8173 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
8174 (eq:SI (match_dup 2) (const_int 0)))]
8175 ""
8176 "
8177{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
8178 operands[1] = gen_rtx (COMPARE, mode,
8179 rs6000_compare_op0, rs6000_compare_op1);
8180 operands[2] = gen_reg_rtx (mode);
8181}")
8182
8183(define_expand "sne"
8184 [(set (match_dup 2) (match_dup 1))
cd2b37d9 8185 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
8186 (ne:SI (match_dup 2) (const_int 0)))]
8187 ""
8188 "
8189{ if (! rs6000_compare_fp_p)
8190 FAIL;
8191
8192 operands[1] = gen_rtx (COMPARE, CCFPmode,
8193 rs6000_compare_op0, rs6000_compare_op1);
8194 operands[2] = gen_reg_rtx (CCFPmode);
8195}")
8196
8197;; A > 0 is best done using the portable sequence, so fail in that case.
8198(define_expand "sgt"
8199 [(set (match_dup 2) (match_dup 1))
cd2b37d9 8200 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
8201 (gt:SI (match_dup 2) (const_int 0)))]
8202 ""
8203 "
8204{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
8205
8206 if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
8207 FAIL;
8208
8209 operands[1] = gen_rtx (COMPARE, mode,
8210 rs6000_compare_op0, rs6000_compare_op1);
8211 operands[2] = gen_reg_rtx (mode);
8212}")
8213
8214;; A < 0 is best done in the portable way for A an integer.
8215(define_expand "slt"
8216 [(set (match_dup 2) (match_dup 1))
cd2b37d9 8217 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
8218 (lt:SI (match_dup 2) (const_int 0)))]
8219 ""
8220 "
8221{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
8222
8223 if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
8224 FAIL;
8225
8226 operands[1] = gen_rtx (COMPARE, mode,
8227 rs6000_compare_op0, rs6000_compare_op1);
8228 operands[2] = gen_reg_rtx (mode);
8229}")
8230
8231(define_expand "sge"
8232 [(set (match_dup 2) (match_dup 1))
cd2b37d9 8233 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
8234 (ge:SI (match_dup 2) (const_int 0)))]
8235 ""
8236 "
8237{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
8238 operands[1] = gen_rtx (COMPARE, mode,
8239 rs6000_compare_op0, rs6000_compare_op1);
8240 operands[2] = gen_reg_rtx (mode);
8241}")
8242
8243;; A <= 0 is best done the portable way for A an integer.
8244(define_expand "sle"
8245 [(set (match_dup 2) (match_dup 1))
cd2b37d9 8246 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
8247 (le:SI (match_dup 2) (const_int 0)))]
8248 ""
8249 "
8250{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
8251
8252 if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
8253 FAIL;
8254
8255 operands[1] = gen_rtx (COMPARE, mode,
8256 rs6000_compare_op0, rs6000_compare_op1);
8257 operands[2] = gen_reg_rtx (mode);
8258}")
8259
8260(define_expand "sgtu"
8261 [(set (match_dup 2) (match_dup 1))
cd2b37d9 8262 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
8263 (gtu:SI (match_dup 2) (const_int 0)))]
8264 ""
8265 "
8266{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
8267 rs6000_compare_op0, rs6000_compare_op1);
8268 operands[2] = gen_reg_rtx (CCUNSmode);
8269}")
8270
8271(define_expand "sltu"
8272 [(set (match_dup 2) (match_dup 1))
cd2b37d9 8273 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
8274 (ltu:SI (match_dup 2) (const_int 0)))]
8275 ""
8276 "
8277{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
8278 rs6000_compare_op0, rs6000_compare_op1);
8279 operands[2] = gen_reg_rtx (CCUNSmode);
8280}")
8281
8282(define_expand "sgeu"
8283 [(set (match_dup 2) (match_dup 1))
cd2b37d9 8284 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
8285 (geu:SI (match_dup 2) (const_int 0)))]
8286 ""
8287 "
8288{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
8289 rs6000_compare_op0, rs6000_compare_op1);
8290 operands[2] = gen_reg_rtx (CCUNSmode);
8291}")
8292
8293(define_expand "sleu"
8294 [(set (match_dup 2) (match_dup 1))
cd2b37d9 8295 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
8296 (leu:SI (match_dup 2) (const_int 0)))]
8297 ""
8298 "
8299{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
8300 rs6000_compare_op0, rs6000_compare_op1);
8301 operands[2] = gen_reg_rtx (CCUNSmode);
8302}")
8303\f
8304;; Here are the actual compare insns.
8305(define_insn ""
8306 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
cd2b37d9 8307 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8308 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
8309 ""
7f340546 8310 "{cmp%I2|cmpw%I2} %0,%1,%2"
1fd4e8c1
RK
8311 [(set_attr "type" "compare")])
8312
266eb58a
DE
8313(define_insn ""
8314 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
8315 (compare:CC (match_operand:DI 1 "gpc_reg_operand" "r")
8316 (match_operand:DI 2 "reg_or_short_operand" "rI")))]
8317 "TARGET_POWERPC64"
8318 "cmpd%I2 %0,%1,%2"
8319 [(set_attr "type" "compare")])
8320
f357808b
RK
8321;; If we are comparing a register for equality with a large constant,
8322;; we can do this with an XOR followed by a compare. But we need a scratch
8323;; register for the result of the XOR.
8324
8325(define_split
8326 [(set (match_operand:CC 0 "cc_reg_operand" "")
cd2b37d9 8327 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
f357808b 8328 (match_operand:SI 2 "non_short_cint_operand" "")))
cd2b37d9 8329 (clobber (match_operand:SI 3 "gpc_reg_operand" ""))]
f357808b
RK
8330 "find_single_use (operands[0], insn, 0)
8331 && (GET_CODE (*find_single_use (operands[0], insn, 0)) == EQ
8332 || GET_CODE (*find_single_use (operands[0], insn, 0)) == NE)"
8333 [(set (match_dup 3) (xor:SI (match_dup 1) (match_dup 4)))
8334 (set (match_dup 0) (compare:CC (match_dup 3) (match_dup 5)))]
8335 "
8336{
8337 /* Get the constant we are comparing against, C, and see what it looks like
8338 sign-extended to 16 bits. Then see what constant could be XOR'ed
8339 with C to get the sign-extended value. */
8340
8341 int c = INTVAL (operands[2]);
8342 int sextc = (c << 16) >> 16;
8343 int xorv = c ^ sextc;
8344
89e9f3a8
MM
8345 operands[4] = GEN_INT (xorv);
8346 operands[5] = GEN_INT (sextc);
f357808b
RK
8347}")
8348
1fd4e8c1
RK
8349(define_insn ""
8350 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
cd2b37d9 8351 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8352 (match_operand:SI 2 "reg_or_u_short_operand" "rI")))]
8353 ""
7f340546 8354 "{cmpl%I2|cmplw%I2} %0,%1,%W2"
1fd4e8c1
RK
8355 [(set_attr "type" "compare")])
8356
266eb58a
DE
8357(define_insn ""
8358 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
8359 (compare:CCUNS (match_operand:DI 1 "gpc_reg_operand" "r")
8360 (match_operand:DI 2 "reg_or_u_short_operand" "rI")))]
8361 ""
8362 "cmpld%I2 %0,%1,%W2"
8363 [(set_attr "type" "compare")])
8364
1fd4e8c1
RK
8365;; The following two insns don't exist as single insns, but if we provide
8366;; them, we can swap an add and compare, which will enable us to overlap more
8367;; of the required delay between a compare and branch. We generate code for
8368;; them by splitting.
8369
8370(define_insn ""
8371 [(set (match_operand:CC 3 "cc_reg_operand" "=y")
cd2b37d9 8372 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8373 (match_operand:SI 2 "short_cint_operand" "i")))
cd2b37d9 8374 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8375 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
8376 ""
baf97f86
RK
8377 "#"
8378 [(set_attr "length" "8")])
7e69e155 8379
1fd4e8c1
RK
8380(define_insn ""
8381 [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
cd2b37d9 8382 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8383 (match_operand:SI 2 "u_short_cint_operand" "i")))
cd2b37d9 8384 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8385 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
8386 ""
baf97f86
RK
8387 "#"
8388 [(set_attr "length" "8")])
7e69e155 8389
1fd4e8c1
RK
8390(define_split
8391 [(set (match_operand:CC 3 "cc_reg_operand" "")
cd2b37d9 8392 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1 8393 (match_operand:SI 2 "short_cint_operand" "")))
cd2b37d9 8394 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
8395 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
8396 ""
8397 [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
8398 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
8399
8400(define_split
8401 [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
cd2b37d9 8402 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1 8403 (match_operand:SI 2 "u_short_cint_operand" "")))
cd2b37d9 8404 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
8405 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
8406 ""
8407 [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
8408 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
8409
8410(define_insn ""
8411 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
cd2b37d9
RK
8412 (compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "f")
8413 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 8414 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
8415 "fcmpu %0,%1,%2"
8416 [(set_attr "type" "fpcompare")])
8417
8418(define_insn ""
8419 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
cd2b37d9
RK
8420 (compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "f")
8421 (match_operand:DF 2 "gpc_reg_operand" "f")))]
d14a6d05 8422 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
8423 "fcmpu %0,%1,%2"
8424 [(set_attr "type" "fpcompare")])
8425\f
8426;; Now we have the scc insns. We can do some combinations because of the
8427;; way the machine works.
8428;;
8429;; Note that this is probably faster if we can put an insn between the
c5defebb
RK
8430;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
8431;; cases the insns below which don't use an intermediate CR field will
8432;; be used instead.
1fd4e8c1 8433(define_insn ""
cd2b37d9 8434 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8435 (match_operator:SI 1 "scc_comparison_operator"
8436 [(match_operand 2 "cc_reg_operand" "y")
8437 (const_int 0)]))]
8438 ""
ca7f5001 8439 "%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%J1,1"
b19003d8 8440 [(set_attr "length" "12")])
1fd4e8c1
RK
8441
8442(define_insn ""
8443 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
8444 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
8445 [(match_operand 2 "cc_reg_operand" "y")
8446 (const_int 0)])
8447 (const_int 0)))
cd2b37d9 8448 (set (match_operand:SI 3 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8449 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8450 ""
ca7f5001 8451 "%D1mfcr %3\;{rlinm.|rlwinm.} %3,%3,%J1,1"
b19003d8
RK
8452 [(set_attr "type" "delayed_compare")
8453 (set_attr "length" "12")])
1fd4e8c1
RK
8454
8455(define_insn ""
cd2b37d9 8456 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8457 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
8458 [(match_operand 2 "cc_reg_operand" "y")
8459 (const_int 0)])
8460 (match_operand:SI 3 "const_int_operand" "n")))]
8461 ""
8462 "*
8463{
8464 int is_bit = ccr_bit (operands[1], 1);
8465 int put_bit = 31 - (INTVAL (operands[3]) & 31);
8466 int count;
8467
8468 if (is_bit >= put_bit)
8469 count = is_bit - put_bit;
8470 else
8471 count = 32 - (put_bit - is_bit);
8472
89e9f3a8
MM
8473 operands[4] = GEN_INT (count);
8474 operands[5] = GEN_INT (put_bit);
1fd4e8c1 8475
ca7f5001 8476 return \"%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%4,%5,%5\";
b19003d8
RK
8477}"
8478 [(set_attr "length" "12")])
1fd4e8c1
RK
8479
8480(define_insn ""
8481 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
8482 (compare:CC
8483 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
8484 [(match_operand 2 "cc_reg_operand" "y")
8485 (const_int 0)])
8486 (match_operand:SI 3 "const_int_operand" "n"))
8487 (const_int 0)))
cd2b37d9 8488 (set (match_operand:SI 4 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8489 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
8490 (match_dup 3)))]
8491 ""
8492 "*
8493{
8494 int is_bit = ccr_bit (operands[1], 1);
8495 int put_bit = 31 - (INTVAL (operands[3]) & 31);
8496 int count;
8497
8498 if (is_bit >= put_bit)
8499 count = is_bit - put_bit;
8500 else
8501 count = 32 - (put_bit - is_bit);
8502
89e9f3a8
MM
8503 operands[5] = GEN_INT (count);
8504 operands[6] = GEN_INT (put_bit);
1fd4e8c1 8505
ca7f5001 8506 return \"%D1mfcr %4\;{rlinm.|rlwinm.} %4,%4,%5,%6,%6\";
1fd4e8c1 8507}"
b19003d8
RK
8508 [(set_attr "type" "delayed_compare")
8509 (set_attr "length" "12")])
1fd4e8c1 8510
c5defebb
RK
8511;; If we are comparing the result of two comparisons, this can be done
8512;; using creqv or crxor.
8513
8514(define_insn ""
8515 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
8516 (compare:CCEQ (match_operator 1 "scc_comparison_operator"
8517 [(match_operand 2 "cc_reg_operand" "y")
8518 (const_int 0)])
8519 (match_operator 3 "scc_comparison_operator"
8520 [(match_operand 4 "cc_reg_operand" "y")
8521 (const_int 0)])))]
8522 "REGNO (operands[2]) != REGNO (operands[4])"
8523 "*
8524{
8525 enum rtx_code code1, code2;
8526
8527 code1 = GET_CODE (operands[1]);
8528 code2 = GET_CODE (operands[3]);
8529
8530 if ((code1 == EQ || code1 == LT || code1 == GT
8531 || code1 == LTU || code1 == GTU
8532 || (code1 != NE && GET_MODE (operands[2]) == CCFPmode))
8533 !=
8534 (code2 == EQ || code2 == LT || code2 == GT
8535 || code2 == LTU || code2 == GTU
8536 || (code2 != NE && GET_MODE (operands[4]) == CCFPmode)))
8537 return \"%C1%C3crxor %E0,%j1,%j3\";
8538 else
8539 return \"%C1%C3creqv %E0,%j1,%j3\";
b19003d8
RK
8540}"
8541 [(set_attr "length" "12")])
c5defebb
RK
8542
8543;; There is a 3 cycle delay between consecutive mfcr instructions
8544;; so it is useful to combine 2 scc instructions to use only one mfcr.
8545
8546(define_peephole
cd2b37d9 8547 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
c5defebb
RK
8548 (match_operator:SI 1 "scc_comparison_operator"
8549 [(match_operand 2 "cc_reg_operand" "y")
8550 (const_int 0)]))
cd2b37d9 8551 (set (match_operand:SI 3 "gpc_reg_operand" "=r")
c5defebb
RK
8552 (match_operator:SI 4 "scc_comparison_operator"
8553 [(match_operand 5 "cc_reg_operand" "y")
8554 (const_int 0)]))]
8555 "REGNO (operands[2]) != REGNO (operands[5])"
ca7f5001 8556 "%D1%D4mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1"
b19003d8 8557 [(set_attr "length" "20")])
c5defebb 8558
1fd4e8c1
RK
8559;; There are some scc insns that can be done directly, without a compare.
8560;; These are faster because they don't involve the communications between
8561;; the FXU and branch units. In fact, we will be replacing all of the
8562;; integer scc insns here or in the portable methods in emit_store_flag.
8563;;
8564;; Also support (neg (scc ..)) since that construct is used to replace
8565;; branches, (plus (scc ..) ..) since that construct is common and
8566;; takes no more insns than scc, and (and (neg (scc ..)) ..) in the
8567;; cases where it is no more expensive than (neg (scc ..)).
8568
8569;; Have reload force a constant into a register for the simple insns that
8570;; otherwise won't accept constants. We do this because it is faster than
8571;; the cmp/mfcr sequence we would otherwise generate.
8572
8573(define_insn ""
cd2b37d9
RK
8574 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
8575 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1
RK
8576 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I")))
8577 (clobber (match_scratch:SI 3 "=r,&r,r,r,r"))]
8578 ""
8579 "@
ca7f5001 8580 xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
71d2371f 8581 {sfi|subfic} %3,%1,0\;{ae|adde} %0,%3,%1
ca7f5001
RK
8582 {xoril|xori} %0,%1,%b2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
8583 {xoriu|xoris} %0,%1,%u2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
8584 {sfi|subfic} %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0"
b19003d8 8585 [(set_attr "length" "12,8,12,12,12")])
1fd4e8c1 8586
a260abc9
DE
8587(define_insn ""
8588 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r")
8589 (eq:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r")
8590 (match_operand:DI 2 "reg_or_cint_operand" "r,O,K,J,I")))
8591 (clobber (match_scratch:DI 3 "=r,&r,r,r,r"))]
8592 "TARGET_POWERPC64"
8593 "@
8594 xor %0,%1,%2\;subfic %3,%0,0\;adde %0,%3,%0
8595 subfic %3,%1,0\;adde %0,%3,%1
8596 xori %0,%1,%b2\;subfic %3,%0,0\;adde %0,%3,%0
8597 xoris %0,%1,%u2\;subfic %3,%0,0\;adde %0,%3,%0
8598 subfic %0,%1,%2\;subfic %3,%0,0\;adde %0,%3,%0"
8599 [(set_attr "length" "12,8,12,12,12")])
8600
1fd4e8c1
RK
8601(define_insn ""
8602 [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,x,x,x")
7e69e155 8603 (compare:CC
cd2b37d9 8604 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1
RK
8605 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
8606 (const_int 0)))
cd2b37d9 8607 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
1fd4e8c1
RK
8608 (eq:SI (match_dup 1) (match_dup 2)))
8609 (clobber (match_scratch:SI 3 "=r,&r,r,r,r"))]
8610 ""
8611 "@
ca7f5001
RK
8612 xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
8613 {sfi|subfic} %3,%1,0\;{ae.|adde.} %0,%3,%1
8614 {xoril|xori} %0,%1,%b2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
8615 {xoriu|xoris} %0,%1,%u2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
8616 {sfi|subfic} %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0"
b19003d8
RK
8617 [(set_attr "type" "compare")
8618 (set_attr "length" "12,8,12,12,12")])
8619
a260abc9
DE
8620(define_insn ""
8621 [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,x,x,x")
8622 (compare:CC
8623 (eq:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r")
8624 (match_operand:DI 2 "reg_or_cint_operand" "r,O,K,J,I"))
8625 (const_int 0)))
8626 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r")
8627 (eq:DI (match_dup 1) (match_dup 2)))
8628 (clobber (match_scratch:DI 3 "=r,&r,r,r,r"))]
8629 "TARGET_POWERPC64"
8630 "@
8631 xor %0,%1,%2\;subfic %3,%0,0\;adde. %0,%3,%0
8632 subfic %3,%1,0\;adde. %0,%3,%1
8633 xori %0,%1,%b2\;subfic %3,%0,0\;adde. %0,%3,%0
8634 xoris %0,%1,%u2\;subfic %3,%0,0\;adde. %0,%3,%0
8635 subfic %0,%1,%2\;subfic %3,%0,0\;adde. %0,%3,%0"
8636 [(set_attr "type" "compare")
8637 (set_attr "length" "12,8,12,12,12")])
8638
b19003d8
RK
8639;; We have insns of the form shown by the first define_insn below. If
8640;; there is something inside the comparison operation, we must split it.
8641(define_split
8642 [(set (match_operand:SI 0 "gpc_reg_operand" "")
8643 (plus:SI (match_operator 1 "comparison_operator"
8644 [(match_operand:SI 2 "" "")
8645 (match_operand:SI 3
8646 "reg_or_cint_operand" "")])
8647 (match_operand:SI 4 "gpc_reg_operand" "")))
8648 (clobber (match_operand:SI 5 "register_operand" ""))]
8649 "! gpc_reg_operand (operands[2], SImode)"
8650 [(set (match_dup 5) (match_dup 2))
8651 (set (match_dup 2) (plus:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
8652 (match_dup 4)))])
1fd4e8c1
RK
8653
8654(define_insn ""
cd2b37d9
RK
8655 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
8656 (plus:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1 8657 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
cd2b37d9 8658 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r")))
1fd4e8c1
RK
8659 (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))]
8660 ""
8661 "@
ca7f5001
RK
8662 xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
8663 {sfi|subfic} %4,%1,0\;{aze|addze} %0,%3
8664 {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
8665 {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
d9d934ef 8666 {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3"
b19003d8 8667 [(set_attr "length" "12,8,12,12,12")])
1fd4e8c1
RK
8668
8669(define_insn ""
8670 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,x")
7e69e155 8671 (compare:CC
1fd4e8c1 8672 (plus:SI
cd2b37d9 8673 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1 8674 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
cd2b37d9 8675 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r"))
1fd4e8c1
RK
8676 (const_int 0)))
8677 (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))]
8678 ""
8679 "@
ca7f5001
RK
8680 xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
8681 {sfi|subfic} %4,%1,0\;{aze.|addze.} %0,%3
8682 {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
8683 {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
8684 {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3"
b19003d8
RK
8685 [(set_attr "type" "compare")
8686 (set_attr "length" "12,8,12,12,12")])
1fd4e8c1
RK
8687
8688(define_insn ""
8689 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x,x,x,x")
7e69e155 8690 (compare:CC
1fd4e8c1 8691 (plus:SI
cd2b37d9 8692 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1 8693 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
cd2b37d9 8694 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r"))
1fd4e8c1 8695 (const_int 0)))
cd2b37d9 8696 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
1fd4e8c1
RK
8697 (plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
8698 (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))]
8699 ""
8700 "@
ca7f5001
RK
8701 xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
8702 {sfi|subfic} %4,%1,0\;{aze.|addze.} %4,%3
8703 {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
8704 {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
8705 {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3"
b19003d8
RK
8706 [(set_attr "type" "compare")
8707 (set_attr "length" "12,8,12,12,12")])
1fd4e8c1
RK
8708
8709(define_insn ""
cd2b37d9 8710 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
deb9225a 8711 (neg:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1
RK
8712 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))))]
8713 ""
8714 "@
ca7f5001
RK
8715 xor %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
8716 {ai|addic} %0,%1,-1\;{sfe|subfe} %0,%0,%0
8717 {xoril|xori} %0,%1,%b2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
8718 {xoriu|xoris} %0,%1,%u2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
8719 {sfi|subfic} %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0"
b19003d8 8720 [(set_attr "length" "12,8,12,12,12")])
1fd4e8c1 8721
ea9be077
MM
8722;; Simplify (ne X (const_int 0)) on the PowerPC. No need to on the Power,
8723;; since it nabs/sr is just as fast.
8724(define_insn ""
8725 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8726 (lshiftrt:SI (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
8727 (const_int 31)))
8728 (clobber (match_scratch:SI 2 "=&r"))]
8729 "!TARGET_POWER"
8730 "{ai|addic} %2,%1,-1\;{sfe|subfe} %0,%2,%1"
8731 [(set_attr "length" "8")])
8732
a260abc9
DE
8733(define_insn ""
8734 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
8735 (lshiftrt:DI (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
8736 (const_int 63)))
8737 (clobber (match_scratch:DI 2 "=&r"))]
8738 "TARGET_POWERPC64"
8739 "addic %2,%1,-1\;subfe %0,%2,%1"
8740 [(set_attr "length" "8")])
8741
1fd4e8c1
RK
8742;; This is what (plus (ne X (const_int 0)) Y) looks like.
8743(define_insn ""
cd2b37d9 8744 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1 8745 (plus:SI (lshiftrt:SI
cd2b37d9 8746 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
1fd4e8c1 8747 (const_int 31))
cd2b37d9 8748 (match_operand:SI 2 "gpc_reg_operand" "r")))
1fd4e8c1
RK
8749 (clobber (match_scratch:SI 3 "=&r"))]
8750 ""
ca7f5001 8751 "{ai|addic} %3,%1,-1\;{aze|addze} %0,%2"
b19003d8 8752 [(set_attr "length" "8")])
1fd4e8c1 8753
a260abc9
DE
8754(define_insn ""
8755 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
8756 (plus:DI (lshiftrt:DI
8757 (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
8758 (const_int 63))
8759 (match_operand:DI 2 "gpc_reg_operand" "r")))
8760 (clobber (match_scratch:DI 3 "=&r"))]
8761 "TARGET_POWERPC64"
8762 "addic %3,%1,-1\;addze %0,%2"
8763 [(set_attr "length" "8")])
8764
1fd4e8c1
RK
8765(define_insn ""
8766 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
8767 (compare:CC
8768 (plus:SI (lshiftrt:SI
cd2b37d9 8769 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
1fd4e8c1 8770 (const_int 31))
cd2b37d9 8771 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1
RK
8772 (const_int 0)))
8773 (clobber (match_scratch:SI 3 "=&r"))]
8774 ""
ca7f5001 8775 "{ai|addic} %3,%1,-1\;{aze.|addze.} %3,%2"
b19003d8
RK
8776 [(set_attr "type" "compare")
8777 (set_attr "length" "8")])
1fd4e8c1 8778
a260abc9
DE
8779(define_insn ""
8780 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
8781 (compare:CC
8782 (plus:DI (lshiftrt:DI
8783 (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
8784 (const_int 63))
8785 (match_operand:DI 2 "gpc_reg_operand" "r"))
8786 (const_int 0)))
8787 (clobber (match_scratch:DI 3 "=&r"))]
8788 "TARGET_POWERPC64"
8789 "addic %3,%1,-1\;addze. %3,%2"
8790 [(set_attr "type" "compare")
8791 (set_attr "length" "8")])
8792
1fd4e8c1
RK
8793(define_insn ""
8794 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
8795 (compare:CC
8796 (plus:SI (lshiftrt:SI
cd2b37d9 8797 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
1fd4e8c1 8798 (const_int 31))
cd2b37d9 8799 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 8800 (const_int 0)))
cd2b37d9 8801 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8802 (plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1))) (const_int 31))
8803 (match_dup 2)))
8804 (clobber (match_scratch:SI 3 "=&r"))]
8805 ""
ca7f5001 8806 "{ai|addic} %3,%1,-1\;{aze.|addze.} %0,%2"
b19003d8
RK
8807 [(set_attr "type" "compare")
8808 (set_attr "length" "8")])
1fd4e8c1 8809
a260abc9
DE
8810(define_insn ""
8811 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
8812 (compare:CC
8813 (plus:DI (lshiftrt:DI
8814 (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
8815 (const_int 63))
8816 (match_operand:DI 2 "gpc_reg_operand" "r"))
8817 (const_int 0)))
8818 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
8819 (plus:DI (lshiftrt:DI (neg:DI (abs:DI (match_dup 1))) (const_int 63))
8820 (match_dup 2)))
8821 (clobber (match_scratch:DI 3 "=&r"))]
8822 "TARGET_POWERPC64"
8823 "addic %3,%1,-1\;addze. %0,%2"
8824 [(set_attr "type" "compare")
8825 (set_attr "length" "8")])
8826
1fd4e8c1 8827(define_insn ""
cd2b37d9
RK
8828 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8829 (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
8830 (match_operand:SI 2 "reg_or_short_operand" "r,O")))
8831 (clobber (match_scratch:SI 3 "=r,X"))]
ca7f5001 8832 "TARGET_POWER"
1fd4e8c1 8833 "@
ca7f5001 8834 doz %3,%2,%1\;{sfi|subfic} %0,%3,0\;{ae|adde} %0,%0,%3
7f340546 8835 {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{sri|srwi} %0,%0,31"
b19003d8 8836 [(set_attr "length" "12")])
1fd4e8c1
RK
8837
8838(define_insn ""
8839 [(set (match_operand:CC 4 "cc_reg_operand" "=x,x")
8840 (compare:CC
cd2b37d9 8841 (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
8842 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
8843 (const_int 0)))
cd2b37d9 8844 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
8845 (le:SI (match_dup 1) (match_dup 2)))
8846 (clobber (match_scratch:SI 3 "=r,X"))]
ca7f5001 8847 "TARGET_POWER"
1fd4e8c1 8848 "@
ca7f5001 8849 doz %3,%2,%1\;{sfi|subfic} %0,%3,0\;{ae.|adde.} %0,%0,%3
7f340546 8850 {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{sri.|srwi.} %0,%0,31"
a473029f 8851 [(set_attr "type" "compare,delayed_compare")
b19003d8 8852 (set_attr "length" "12")])
1fd4e8c1
RK
8853
8854(define_insn ""
cd2b37d9
RK
8855 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8856 (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 8857 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
cd2b37d9 8858 (match_operand:SI 3 "gpc_reg_operand" "r,r")))
1fd4e8c1 8859 (clobber (match_scratch:SI 4 "=&r,&r"))]
ca7f5001 8860 "TARGET_POWER"
1fd4e8c1 8861 "@
ca7f5001
RK
8862 doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
8863 {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze|addze} %0,%3"
b19003d8 8864 [(set_attr "length" "12")])
1fd4e8c1
RK
8865
8866(define_insn ""
8867 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
8868 (compare:CC
cd2b37d9 8869 (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 8870 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
cd2b37d9 8871 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1
RK
8872 (const_int 0)))
8873 (clobber (match_scratch:SI 4 "=&r,&r"))]
ca7f5001 8874 "TARGET_POWER"
1fd4e8c1 8875 "@
ca7f5001
RK
8876 doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
8877 {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze.|addze.} %4,%3"
b19003d8
RK
8878 [(set_attr "type" "compare")
8879 (set_attr "length" "12")])
1fd4e8c1
RK
8880
8881(define_insn ""
8882 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
8883 (compare:CC
cd2b37d9 8884 (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 8885 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
cd2b37d9 8886 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 8887 (const_int 0)))
cd2b37d9 8888 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
8889 (plus:SI (le:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
8890 (clobber (match_scratch:SI 4 "=&r,&r"))]
ca7f5001 8891 "TARGET_POWER"
1fd4e8c1 8892 "@
ca7f5001
RK
8893 doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
8894 {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze.|addze.} %0,%3"
b19003d8
RK
8895 [(set_attr "type" "compare")
8896 (set_attr "length" "12")])
1fd4e8c1
RK
8897
8898(define_insn ""
cd2b37d9
RK
8899 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8900 (neg:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 8901 (match_operand:SI 2 "reg_or_short_operand" "r,O"))))]
ca7f5001 8902 "TARGET_POWER"
1fd4e8c1 8903 "@
ca7f5001
RK
8904 doz %0,%2,%1\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
8905 {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{srai|srawi} %0,%0,31"
b19003d8 8906 [(set_attr "length" "12")])
1fd4e8c1
RK
8907
8908(define_insn ""
cd2b37d9
RK
8909 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8910 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8911 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
8912 ""
ca7f5001 8913 "{sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0"
b19003d8 8914 [(set_attr "length" "12")])
1fd4e8c1
RK
8915
8916(define_insn ""
8917 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
8918 (compare:CC
cd2b37d9 8919 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8920 (match_operand:SI 2 "reg_or_short_operand" "rI"))
8921 (const_int 0)))
cd2b37d9 8922 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8923 (leu:SI (match_dup 1) (match_dup 2)))]
8924 ""
ca7f5001 8925 "{sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0"
b19003d8
RK
8926 [(set_attr "type" "compare")
8927 (set_attr "length" "12")])
1fd4e8c1
RK
8928
8929(define_insn ""
cd2b37d9
RK
8930 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8931 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8932 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 8933 (match_operand:SI 3 "gpc_reg_operand" "r")))
1fd4e8c1
RK
8934 (clobber (match_scratch:SI 4 "=&r"))]
8935 ""
ca7f5001 8936 "{sf%I2|subf%I2c} %4,%1,%2\;{aze|addze} %0,%3"
b19003d8 8937 [(set_attr "length" "8")])
1fd4e8c1
RK
8938
8939(define_insn ""
8940 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
8941 (compare:CC
cd2b37d9 8942 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8943 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 8944 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1
RK
8945 (const_int 0)))
8946 (clobber (match_scratch:SI 4 "=&r"))]
8947 ""
ca7f5001 8948 "{sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %4,%3"
b19003d8
RK
8949 [(set_attr "type" "compare")
8950 (set_attr "length" "8")])
1fd4e8c1
RK
8951
8952(define_insn ""
8953 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
8954 (compare:CC
cd2b37d9 8955 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8956 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 8957 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1 8958 (const_int 0)))
cd2b37d9 8959 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8960 (plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
8961 (clobber (match_scratch:SI 4 "=&r"))]
8962 ""
ca7f5001 8963 "{sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %0,%3"
b19003d8
RK
8964 [(set_attr "type" "compare")
8965 (set_attr "length" "8")])
1fd4e8c1
RK
8966
8967(define_insn ""
cd2b37d9
RK
8968 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8969 (neg:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8970 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
8971 ""
ca7f5001 8972 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;nand %0,%0,%0"
b19003d8 8973 [(set_attr "length" "12")])
1fd4e8c1
RK
8974
8975(define_insn ""
cd2b37d9 8976 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1 8977 (and:SI (neg:SI
cd2b37d9 8978 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8979 (match_operand:SI 2 "reg_or_short_operand" "rI")))
cd2b37d9 8980 (match_operand:SI 3 "gpc_reg_operand" "r")))
1fd4e8c1
RK
8981 (clobber (match_scratch:SI 4 "=&r"))]
8982 ""
ca7f5001 8983 "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4"
b19003d8 8984 [(set_attr "length" "12")])
1fd4e8c1
RK
8985
8986(define_insn ""
8987 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
8988 (compare:CC
8989 (and:SI (neg:SI
cd2b37d9 8990 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8991 (match_operand:SI 2 "reg_or_short_operand" "rI")))
cd2b37d9 8992 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1
RK
8993 (const_int 0)))
8994 (clobber (match_scratch:SI 4 "=&r"))]
8995 ""
ca7f5001 8996 "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4"
b19003d8
RK
8997 [(set_attr "type" "compare")
8998 (set_attr "length" "12")])
1fd4e8c1
RK
8999
9000(define_insn ""
9001 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
9002 (compare:CC
9003 (and:SI (neg:SI
cd2b37d9 9004 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 9005 (match_operand:SI 2 "reg_or_short_operand" "rI")))
cd2b37d9 9006 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1 9007 (const_int 0)))
cd2b37d9 9008 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
9009 (and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))
9010 (clobber (match_scratch:SI 4 "=&r"))]
9011 ""
ca7f5001 9012 "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4"
b19003d8
RK
9013 [(set_attr "type" "compare")
9014 (set_attr "length" "12")])
1fd4e8c1
RK
9015
9016(define_insn ""
cd2b37d9
RK
9017 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9018 (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 9019 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
ca7f5001 9020 "TARGET_POWER"
7f340546 9021 "doz%I2 %0,%1,%2\;nabs %0,%0\;{sri|srwi} %0,%0,31"
b19003d8 9022 [(set_attr "length" "12")])
1fd4e8c1
RK
9023
9024(define_insn ""
ad8bd902 9025 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1fd4e8c1 9026 (compare:CC
cd2b37d9 9027 (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
9028 (match_operand:SI 2 "reg_or_short_operand" "rI"))
9029 (const_int 0)))
cd2b37d9 9030 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1 9031 (lt:SI (match_dup 1) (match_dup 2)))]
ca7f5001 9032 "TARGET_POWER"
7f340546 9033 "doz%I2 %0,%1,%2\;nabs %0,%0\;{sri.|srwi.} %0,%0,31"
b19003d8
RK
9034 [(set_attr "type" "delayed_compare")
9035 (set_attr "length" "12")])
1fd4e8c1
RK
9036
9037(define_insn ""
cd2b37d9
RK
9038 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9039 (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 9040 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 9041 (match_operand:SI 3 "gpc_reg_operand" "r")))
1fd4e8c1 9042 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
9043 "TARGET_POWER"
9044 "doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze|addze} %0,%3"
b19003d8 9045 [(set_attr "length" "12")])
1fd4e8c1
RK
9046
9047(define_insn ""
ad8bd902 9048 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1fd4e8c1 9049 (compare:CC
cd2b37d9 9050 (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 9051 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 9052 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1
RK
9053 (const_int 0)))
9054 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
9055 "TARGET_POWER"
9056 "doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze.|addze.} %4,%3"
b19003d8
RK
9057 [(set_attr "type" "compare")
9058 (set_attr "length" "12")])
1fd4e8c1
RK
9059
9060(define_insn ""
ad8bd902 9061 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
1fd4e8c1 9062 (compare:CC
cd2b37d9 9063 (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 9064 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 9065 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1 9066 (const_int 0)))
cd2b37d9 9067 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
9068 (plus:SI (lt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
9069 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
9070 "TARGET_POWER"
9071 "doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze.|addze.} %0,%3"
b19003d8
RK
9072 [(set_attr "type" "compare")
9073 (set_attr "length" "12")])
1fd4e8c1
RK
9074
9075(define_insn ""
cd2b37d9
RK
9076 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9077 (neg:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 9078 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
ca7f5001
RK
9079 "TARGET_POWER"
9080 "doz%I2 %0,%1,%2\;nabs %0,%0\;{srai|srawi} %0,%0,31"
b19003d8 9081 [(set_attr "length" "12")])
1fd4e8c1
RK
9082
9083(define_insn ""
cd2b37d9
RK
9084 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
9085 (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
9086 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))]
9087 ""
9088 "@
ca7f5001
RK
9089 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg %0,%0
9090 {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg %0,%0"
b19003d8 9091 [(set_attr "length" "12")])
1fd4e8c1
RK
9092
9093(define_insn ""
9094 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
9095 (compare:CC
cd2b37d9 9096 (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
9097 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
9098 (const_int 0)))
cd2b37d9 9099 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
9100 (ltu:SI (match_dup 1) (match_dup 2)))]
9101 ""
9102 "@
ca7f5001
RK
9103 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg. %0,%0
9104 {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0"
b19003d8
RK
9105 [(set_attr "type" "compare")
9106 (set_attr "length" "12")])
1fd4e8c1
RK
9107
9108(define_insn ""
cd2b37d9
RK
9109 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
9110 (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
1fd4e8c1
RK
9111 (match_operand:SI 2 "reg_or_neg_short_operand" "r,r,P,P"))
9112 (match_operand:SI 3 "reg_or_short_operand" "r,I,r,I")))
9113 (clobber (match_scratch:SI 4 "=&r,r,&r,r"))]
9114 ""
9115 "@
ca7f5001
RK
9116 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
9117 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
9118 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
9119 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3"
b19003d8 9120 [(set_attr "length" "12")])
1fd4e8c1
RK
9121
9122(define_insn ""
3d91674b 9123 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
1fd4e8c1 9124 (compare:CC
3d91674b
RK
9125 (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
9126 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
9127 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 9128 (const_int 0)))
3d91674b 9129 (clobber (match_scratch:SI 4 "=&r,&r"))]
1fd4e8c1
RK
9130 ""
9131 "@
ca7f5001
RK
9132 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3
9133 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3"
b19003d8
RK
9134 [(set_attr "type" "compare")
9135 (set_attr "length" "12")])
1fd4e8c1
RK
9136
9137(define_insn ""
3d91674b 9138 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
1fd4e8c1 9139 (compare:CC
3d91674b
RK
9140 (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
9141 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
9142 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 9143 (const_int 0)))
3d91674b 9144 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1 9145 (plus:SI (ltu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
3d91674b 9146 (clobber (match_scratch:SI 4 "=&r,&r"))]
1fd4e8c1
RK
9147 ""
9148 "@
ca7f5001
RK
9149 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3
9150 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3"
b19003d8
RK
9151 [(set_attr "type" "compare")
9152 (set_attr "length" "12")])
1fd4e8c1
RK
9153
9154(define_insn ""
cd2b37d9
RK
9155 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
9156 (neg:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
9157 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))))]
9158 ""
9159 "@
ca7f5001
RK
9160 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0
9161 {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0"
b19003d8 9162 [(set_attr "length" "8")])
1fd4e8c1
RK
9163
9164(define_insn ""
cd2b37d9
RK
9165 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9166 (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
9167 (match_operand:SI 2 "reg_or_short_operand" "rI")))
9168 (clobber (match_scratch:SI 3 "=r"))]
ca7f5001
RK
9169 "TARGET_POWER"
9170 "doz%I2 %3,%1,%2\;{sfi|subfic} %0,%3,0\;{ae|adde} %0,%0,%3"
b19003d8 9171 [(set_attr "length" "12")])
1fd4e8c1
RK
9172
9173(define_insn ""
9174 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
9175 (compare:CC
cd2b37d9 9176 (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
9177 (match_operand:SI 2 "reg_or_short_operand" "rI"))
9178 (const_int 0)))
cd2b37d9 9179 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
9180 (ge:SI (match_dup 1) (match_dup 2)))
9181 (clobber (match_scratch:SI 3 "=r"))]
ca7f5001
RK
9182 "TARGET_POWER"
9183 "doz%I2 %3,%1,%2\;{sfi|subfic} %0,%3,0\;{ae.|adde.} %0,%0,%3"
b19003d8
RK
9184 [(set_attr "type" "compare")
9185 (set_attr "length" "12")])
1fd4e8c1
RK
9186
9187(define_insn ""
cd2b37d9
RK
9188 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9189 (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 9190 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 9191 (match_operand:SI 3 "gpc_reg_operand" "r")))
1fd4e8c1 9192 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
9193 "TARGET_POWER"
9194 "doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3"
b19003d8 9195 [(set_attr "length" "12")])
1fd4e8c1
RK
9196
9197(define_insn ""
9198 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
9199 (compare:CC
cd2b37d9 9200 (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 9201 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 9202 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1
RK
9203 (const_int 0)))
9204 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
9205 "TARGET_POWER"
9206 "doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3"
b19003d8
RK
9207 [(set_attr "type" "compare")
9208 (set_attr "length" "12")])
1fd4e8c1
RK
9209
9210(define_insn ""
9211 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
9212 (compare:CC
cd2b37d9 9213 (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 9214 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 9215 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1 9216 (const_int 0)))
cd2b37d9 9217 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
9218 (plus:SI (ge:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
9219 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
9220 "TARGET_POWER"
9221 "doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3"
b19003d8
RK
9222 [(set_attr "type" "compare")
9223 (set_attr "length" "12")])
1fd4e8c1
RK
9224
9225(define_insn ""
cd2b37d9
RK
9226 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9227 (neg:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 9228 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
ca7f5001
RK
9229 "TARGET_POWER"
9230 "doz%I2 %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0"
b19003d8 9231 [(set_attr "length" "12")])
1fd4e8c1
RK
9232
9233;; This is (and (neg (ge X (const_int 0))) Y).
9234(define_insn ""
cd2b37d9 9235 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
9236 (and:SI (neg:SI
9237 (lshiftrt:SI
cd2b37d9 9238 (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1fd4e8c1 9239 (const_int 31)))
cd2b37d9 9240 (match_operand:SI 2 "gpc_reg_operand" "r")))
1fd4e8c1
RK
9241 (clobber (match_scratch:SI 3 "=&r"))]
9242 ""
ca7f5001 9243 "{srai|srawi} %3,%1,31\;andc %0,%2,%3"
b19003d8 9244 [(set_attr "length" "8")])
1fd4e8c1
RK
9245
9246(define_insn ""
9247 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
9248 (compare:CC
9249 (and:SI (neg:SI
9250 (lshiftrt:SI
cd2b37d9 9251 (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1fd4e8c1 9252 (const_int 31)))
cd2b37d9 9253 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1
RK
9254 (const_int 0)))
9255 (clobber (match_scratch:SI 3 "=&r"))]
9256 ""
ca7f5001 9257 "{srai|srawi} %3,%1,31\;andc. %3,%2,%3"
b19003d8
RK
9258 [(set_attr "type" "compare")
9259 (set_attr "length" "8")])
1fd4e8c1
RK
9260
9261(define_insn ""
9262 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
9263 (compare:CC
9264 (and:SI (neg:SI
9265 (lshiftrt:SI
cd2b37d9 9266 (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1fd4e8c1 9267 (const_int 31)))
cd2b37d9 9268 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 9269 (const_int 0)))
cd2b37d9 9270 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
9271 (and:SI (neg:SI (lshiftrt:SI (not:SI (match_dup 1))
9272 (const_int 31)))
9273 (match_dup 2)))
9274 (clobber (match_scratch:SI 3 "=&r"))]
9275 ""
ca7f5001 9276 "{srai|srawi} %3,%1,31\;andc. %0,%2,%3"
b19003d8
RK
9277 [(set_attr "type" "compare")
9278 (set_attr "length" "8")])
1fd4e8c1
RK
9279
9280(define_insn ""
cd2b37d9
RK
9281 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
9282 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
9283 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))]
9284 ""
9285 "@
ca7f5001
RK
9286 {sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0
9287 {ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0"
b19003d8 9288 [(set_attr "length" "12")])
1fd4e8c1
RK
9289
9290(define_insn ""
9291 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
9292 (compare:CC
cd2b37d9 9293 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
9294 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
9295 (const_int 0)))
cd2b37d9 9296 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
9297 (geu:SI (match_dup 1) (match_dup 2)))]
9298 ""
9299 "@
ca7f5001
RK
9300 {sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0
9301 {ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0"
b19003d8
RK
9302 [(set_attr "type" "compare")
9303 (set_attr "length" "12")])
1fd4e8c1
RK
9304
9305(define_insn ""
cd2b37d9
RK
9306 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
9307 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 9308 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
cd2b37d9 9309 (match_operand:SI 3 "gpc_reg_operand" "r,r")))
1fd4e8c1
RK
9310 (clobber (match_scratch:SI 4 "=&r,&r"))]
9311 ""
9312 "@
ca7f5001
RK
9313 {sf|subfc} %4,%2,%1\;{aze|addze} %0,%3
9314 {ai|addic} %4,%1,%n2\;{aze|addze} %0,%3"
b19003d8 9315 [(set_attr "length" "8")])
1fd4e8c1
RK
9316
9317(define_insn ""
9318 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
9319 (compare:CC
cd2b37d9 9320 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 9321 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
cd2b37d9 9322 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1
RK
9323 (const_int 0)))
9324 (clobber (match_scratch:SI 4 "=&r,&r"))]
9325 ""
9326 "@
ca7f5001
RK
9327 {sf|subfc} %4,%2,%1\;{aze.|addze.} %4,%3
9328 {ai|addic} %4,%1,%n2\;{aze.|addze.} %4,%3"
b19003d8
RK
9329 [(set_attr "type" "compare")
9330 (set_attr "length" "8")])
1fd4e8c1
RK
9331
9332(define_insn ""
9333 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
9334 (compare:CC
cd2b37d9 9335 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 9336 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
cd2b37d9 9337 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 9338 (const_int 0)))
cd2b37d9 9339 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
9340 (plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
9341 (clobber (match_scratch:SI 4 "=&r,&r"))]
9342 ""
9343 "@
ca7f5001
RK
9344 {sf|subfc} %4,%2,%1\;{aze.|addze.} %0,%3
9345 {ai|addic} %4,%1,%n2\;{aze.|addze.} %4,%3"
b19003d8
RK
9346 [(set_attr "type" "compare")
9347 (set_attr "length" "8")])
1fd4e8c1
RK
9348
9349(define_insn ""
cd2b37d9
RK
9350 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
9351 (neg:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
9352 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))]
9353 ""
9354 "@
ca7f5001 9355 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;nand %0,%0,%0
8106dc08 9356 {sfi|subfic} %0,%1,-1\;{a%I2|add%I2c} %0,%0,%2\;{sfe|subfe} %0,%0,%0"
b19003d8 9357 [(set_attr "length" "12")])
1fd4e8c1
RK
9358
9359(define_insn ""
cd2b37d9 9360 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1 9361 (and:SI (neg:SI
cd2b37d9 9362 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 9363 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))
cd2b37d9 9364 (match_operand:SI 3 "gpc_reg_operand" "r,r")))
1fd4e8c1
RK
9365 (clobber (match_scratch:SI 4 "=&r,&r"))]
9366 ""
9367 "@
ca7f5001
RK
9368 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4
9369 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4"
b19003d8 9370 [(set_attr "length" "12")])
1fd4e8c1
RK
9371
9372(define_insn ""
9373 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
9374 (compare:CC
9375 (and:SI (neg:SI
cd2b37d9 9376 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 9377 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))
cd2b37d9 9378 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1
RK
9379 (const_int 0)))
9380 (clobber (match_scratch:SI 4 "=&r,&r"))]
9381 ""
9382 "@
ca7f5001
RK
9383 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4
9384 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4"
b19003d8
RK
9385 [(set_attr "type" "compare")
9386 (set_attr "length" "12")])
1fd4e8c1
RK
9387
9388(define_insn ""
9389 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
9390 (compare:CC
9391 (and:SI (neg:SI
cd2b37d9 9392 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 9393 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))
cd2b37d9 9394 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 9395 (const_int 0)))
cd2b37d9 9396 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
9397 (and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))
9398 (clobber (match_scratch:SI 4 "=&r,&r"))]
9399 ""
9400 "@
ca7f5001
RK
9401 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4
9402 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4"
b19003d8
RK
9403 [(set_attr "type" "compare")
9404 (set_attr "length" "12")])
1fd4e8c1
RK
9405
9406(define_insn ""
cd2b37d9
RK
9407 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9408 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
9409 (const_int 0)))]
9410 ""
ca7f5001 9411 "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri|srwi} %0,%0,31"
b19003d8 9412 [(set_attr "length" "12")])
1fd4e8c1
RK
9413
9414(define_insn ""
9415 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
9416 (compare:CC
cd2b37d9 9417 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
9418 (const_int 0))
9419 (const_int 0)))
cd2b37d9 9420 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
9421 (gt:SI (match_dup 1) (const_int 0)))]
9422 ""
ca7f5001 9423 "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri.|srwi.} %0,%0,31"
b19003d8
RK
9424 [(set_attr "type" "delayed_compare")
9425 (set_attr "length" "12")])
1fd4e8c1
RK
9426
9427(define_insn ""
cd2b37d9
RK
9428 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9429 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 9430 (match_operand:SI 2 "reg_or_short_operand" "r")))]
ca7f5001
RK
9431 "TARGET_POWER"
9432 "doz %0,%2,%1\;nabs %0,%0\;{sri|srwi} %0,%0,31"
b19003d8 9433 [(set_attr "length" "12")])
1fd4e8c1
RK
9434
9435(define_insn ""
9436 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
9437 (compare:CC
cd2b37d9 9438 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
9439 (match_operand:SI 2 "reg_or_short_operand" "r"))
9440 (const_int 0)))
cd2b37d9 9441 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1 9442 (gt:SI (match_dup 1) (match_dup 2)))]
ca7f5001
RK
9443 "TARGET_POWER"
9444 "doz %0,%2,%1\;nabs %0,%0\;{sri.|srwi.} %0,%0,31"
b19003d8
RK
9445 [(set_attr "type" "delayed_compare")
9446 (set_attr "length" "12")])
1fd4e8c1
RK
9447
9448(define_insn ""
cd2b37d9
RK
9449 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9450 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 9451 (const_int 0))
cd2b37d9 9452 (match_operand:SI 2 "gpc_reg_operand" "r")))
1fd4e8c1
RK
9453 (clobber (match_scratch:SI 3 "=&r"))]
9454 ""
ca7f5001 9455 "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze|addze} %0,%2"
b19003d8 9456 [(set_attr "length" "12")])
1fd4e8c1
RK
9457
9458(define_insn ""
9459 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
9460 (compare:CC
cd2b37d9 9461 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 9462 (const_int 0))
cd2b37d9 9463 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1
RK
9464 (const_int 0)))
9465 (clobber (match_scratch:SI 3 "=&r"))]
9466 ""
ca7f5001 9467 "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %0,%2"
b19003d8
RK
9468 [(set_attr "type" "compare")
9469 (set_attr "length" "12")])
1fd4e8c1
RK
9470
9471(define_insn ""
9472 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
9473 (compare:CC
cd2b37d9 9474 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 9475 (const_int 0))
cd2b37d9 9476 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 9477 (const_int 0)))
cd2b37d9 9478 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
9479 (plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2)))
9480 (clobber (match_scratch:SI 3 "=&r"))]
9481 ""
ca7f5001 9482 "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %3,%2"
b19003d8
RK
9483 [(set_attr "type" "compare")
9484 (set_attr "length" "12")])
1fd4e8c1
RK
9485
9486(define_insn ""
cd2b37d9
RK
9487 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9488 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 9489 (match_operand:SI 2 "reg_or_short_operand" "r"))
cd2b37d9 9490 (match_operand:SI 3 "gpc_reg_operand" "r")))
1fd4e8c1 9491 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
9492 "TARGET_POWER"
9493 "doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze|addze} %0,%3"
b19003d8 9494 [(set_attr "length" "12")])
1fd4e8c1
RK
9495
9496(define_insn ""
9497 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
9498 (compare:CC
cd2b37d9 9499 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 9500 (match_operand:SI 2 "reg_or_short_operand" "r"))
cd2b37d9 9501 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1
RK
9502 (const_int 0)))
9503 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
9504 "TARGET_POWER"
9505 "doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze.|addze.} %4,%3"
b19003d8
RK
9506 [(set_attr "type" "compare")
9507 (set_attr "length" "12")])
1fd4e8c1
RK
9508
9509(define_insn ""
9510 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
9511 (compare:CC
cd2b37d9 9512 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 9513 (match_operand:SI 2 "reg_or_short_operand" "r"))
cd2b37d9 9514 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1 9515 (const_int 0)))
cd2b37d9 9516 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
9517 (plus:SI (gt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
9518 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
9519 "TARGET_POWER"
9520 "doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze.|addze.} %0,%3"
b19003d8
RK
9521 [(set_attr "type" "compare")
9522 (set_attr "length" "12")])
1fd4e8c1
RK
9523
9524(define_insn ""
cd2b37d9
RK
9525 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9526 (neg:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
9527 (const_int 0))))]
9528 ""
ca7f5001 9529 "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{srai|srawi} %0,%0,31"
b19003d8 9530 [(set_attr "length" "12")])
1fd4e8c1
RK
9531
9532(define_insn ""
cd2b37d9
RK
9533 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9534 (neg:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 9535 (match_operand:SI 2 "reg_or_short_operand" "r"))))]
ca7f5001
RK
9536 "TARGET_POWER"
9537 "doz %0,%2,%1\;nabs %0,%0\;{srai|srawi} %0,%0,31"
b19003d8 9538 [(set_attr "length" "12")])
1fd4e8c1
RK
9539
9540(define_insn ""
cd2b37d9
RK
9541 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9542 (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
9543 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
9544 ""
ca7f5001 9545 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg %0,%0"
b19003d8 9546 [(set_attr "length" "12")])
1fd4e8c1
RK
9547
9548(define_insn ""
9549 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
9550 (compare:CC
cd2b37d9 9551 (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
9552 (match_operand:SI 2 "reg_or_short_operand" "rI"))
9553 (const_int 0)))
cd2b37d9 9554 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
9555 (gtu:SI (match_dup 1) (match_dup 2)))]
9556 ""
ca7f5001 9557 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0"
b19003d8
RK
9558 [(set_attr "type" "compare")
9559 (set_attr "length" "12")])
1fd4e8c1
RK
9560
9561(define_insn ""
00751805
RK
9562 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
9563 (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r")
9564 (match_operand:SI 2 "reg_or_short_operand" "I,r,rI"))
9565 (match_operand:SI 3 "reg_or_short_operand" "r,r,I")))
9566 (clobber (match_scratch:SI 4 "=&r,&r,&r"))]
1fd4e8c1 9567 ""
00751805 9568 "@
ca7f5001
RK
9569 {ai|addic} %4,%1,%k2\;{aze|addze} %0,%3
9570 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
9571 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3"
b19003d8 9572 [(set_attr "length" "8,12,12")])
1fd4e8c1
RK
9573
9574(define_insn ""
3d91674b 9575 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
1fd4e8c1 9576 (compare:CC
3d91674b
RK
9577 (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
9578 (match_operand:SI 2 "reg_or_short_operand" "I,r"))
9579 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 9580 (const_int 0)))
3d91674b 9581 (clobber (match_scratch:SI 4 "=&r,&r"))]
1fd4e8c1 9582 ""
00751805 9583 "@
ca7f5001
RK
9584 {ai|addic} %4,%1,%k2\;{aze.|addze.} %0,%3
9585 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3"
b19003d8 9586 [(set_attr "type" "compare")
3d91674b 9587 (set_attr "length" "8,12")])
1fd4e8c1
RK
9588
9589(define_insn ""
3d91674b 9590 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
1fd4e8c1 9591 (compare:CC
3d91674b
RK
9592 (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
9593 (match_operand:SI 2 "reg_or_short_operand" "I,r"))
9594 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 9595 (const_int 0)))
3d91674b 9596 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1 9597 (plus:SI (gtu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
3d91674b 9598 (clobber (match_scratch:SI 4 "=&r,&r"))]
1fd4e8c1 9599 ""
00751805 9600 "@
ca7f5001
RK
9601 {ai|addic} %4,%1,%k2\;{aze.|addze.} %0,%3
9602 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3"
b19003d8 9603 [(set_attr "type" "compare")
3d91674b 9604 (set_attr "length" "8,12")])
1fd4e8c1
RK
9605
9606(define_insn ""
cd2b37d9
RK
9607 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9608 (neg:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
9609 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
9610 ""
ca7f5001 9611 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0"
b19003d8 9612 [(set_attr "length" "8")])
1fd4e8c1
RK
9613\f
9614;; Define both directions of branch and return. If we need a reload
9615;; register, we'd rather use CR0 since it is much easier to copy a
9616;; register CC value to there.
9617
9618(define_insn ""
9619 [(set (pc)
9620 (if_then_else (match_operator 1 "branch_comparison_operator"
9621 [(match_operand 2
9622 "cc_reg_operand" "x,?y")
9623 (const_int 0)])
9624 (label_ref (match_operand 0 "" ""))
9625 (pc)))]
9626 ""
b19003d8
RK
9627 "*
9628{
9629 if (get_attr_length (insn) == 8)
9630 return \"%C1bc %t1,%j1,%l0\";
9631 else
c81bebd7
MM
9632 return \"%C1bc %T1,%j1,%$+8\;b %l0\";
9633
b19003d8
RK
9634}"
9635 [(set_attr "type" "branch")])
9636
1fd4e8c1
RK
9637(define_insn ""
9638 [(set (pc)
9639 (if_then_else (match_operator 0 "branch_comparison_operator"
9640 [(match_operand 1
9641 "cc_reg_operand" "x,?y")
9642 (const_int 0)])
9643 (return)
9644 (pc)))]
9645 "direct_return ()"
ca7f5001 9646 "{%C0bcr|%C0bclr} %t0,%j0"
b7ff3d82
DE
9647 [(set_attr "type" "branch")
9648 (set_attr "length" "8")])
1fd4e8c1
RK
9649
9650(define_insn ""
9651 [(set (pc)
9652 (if_then_else (match_operator 1 "branch_comparison_operator"
9653 [(match_operand 2
9654 "cc_reg_operand" "x,?y")
9655 (const_int 0)])
9656 (pc)
9657 (label_ref (match_operand 0 "" ""))))]
9658 ""
b19003d8
RK
9659 "*
9660{
9661 if (get_attr_length (insn) == 8)
9662 return \"%C1bc %T1,%j1,%l0\";
9663 else
c81bebd7 9664 return \"%C1bc %t1,%j1,%$+8\;b %l0\";
b19003d8
RK
9665}"
9666 [(set_attr "type" "branch")])
1fd4e8c1
RK
9667
9668(define_insn ""
9669 [(set (pc)
9670 (if_then_else (match_operator 0 "branch_comparison_operator"
9671 [(match_operand 1
9672 "cc_reg_operand" "x,?y")
9673 (const_int 0)])
9674 (pc)
9675 (return)))]
9676 "direct_return ()"
ca7f5001 9677 "{%C0bcr|%C0bclr} %T0,%j0"
b7ff3d82
DE
9678 [(set_attr "type" "branch")
9679 (set_attr "length" "8")])
1fd4e8c1
RK
9680
9681;; Unconditional branch and return.
9682
9683(define_insn "jump"
9684 [(set (pc)
9685 (label_ref (match_operand 0 "" "")))]
9686 ""
b7ff3d82
DE
9687 "b %l0"
9688 [(set_attr "type" "branch")])
1fd4e8c1
RK
9689
9690(define_insn "return"
9691 [(return)]
9692 "direct_return ()"
324e52cc
TG
9693 "{br|blr}"
9694 [(set_attr "type" "jmpreg")])
1fd4e8c1
RK
9695
9696(define_insn "indirect_jump"
9697 [(set (pc) (match_operand:SI 0 "register_operand" "c,l"))]
9698 ""
9699 "@
9700 bctr
324e52cc
TG
9701 {br|blr}"
9702 [(set_attr "type" "jmpreg")])
1fd4e8c1 9703
266eb58a
DE
9704(define_insn ""
9705 [(set (pc) (match_operand:DI 0 "register_operand" "c,l"))]
9706 "TARGET_POWERPC64"
9707 "@
9708 bctr
9709 {br|blr}"
9710 [(set_attr "type" "jmpreg")])
9711
1fd4e8c1
RK
9712;; Table jump for switch statements:
9713(define_expand "tablejump"
e6ca2c17
DE
9714 [(use (match_operand 0 "" ""))
9715 (use (label_ref (match_operand 1 "" "")))]
9716 ""
9717 "
9718{
9719 if (TARGET_32BIT)
9720 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
9721 else
9722 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
9723 DONE;
9724}")
9725
9726(define_expand "tablejumpsi"
1fd4e8c1
RK
9727 [(set (match_dup 3)
9728 (plus:SI (match_operand:SI 0 "" "")
9729 (match_dup 2)))
9730 (parallel [(set (pc) (match_dup 3))
9731 (use (label_ref (match_operand 1 "" "")))])]
9732 ""
9733 "
9734{ operands[0] = force_reg (SImode, operands[0]);
9735 operands[2] = force_reg (SImode, gen_rtx (LABEL_REF, VOIDmode, operands[1]));
9736 operands[3] = gen_reg_rtx (SImode);
9737}")
9738
e6ca2c17
DE
9739(define_expand "tablejumpdi"
9740 [(set (match_dup 3)
9741 (plus:DI (match_operand:DI 0 "" "")
9742 (match_dup 2)))
9743 (parallel [(set (pc) (match_dup 3))
9744 (use (label_ref (match_operand 1 "" "")))])]
9745 ""
9746 "
9747{ operands[0] = force_reg (DImode, operands[0]);
9748 operands[2] = force_reg (DImode, gen_rtx (LABEL_REF, VOIDmode, operands[1]));
9749 operands[3] = gen_reg_rtx (DImode);
9750}")
9751
1fd4e8c1
RK
9752(define_insn ""
9753 [(set (pc)
740ab4a2 9754 (match_operand:SI 0 "register_operand" "c,l"))
1fd4e8c1
RK
9755 (use (label_ref (match_operand 1 "" "")))]
9756 ""
9757 "@
9758 bctr
a6845123
RK
9759 {br|blr}"
9760 [(set_attr "type" "jmpreg")])
1fd4e8c1 9761
266eb58a
DE
9762(define_insn ""
9763 [(set (pc)
9764 (match_operand:DI 0 "register_operand" "c,l"))
9765 (use (label_ref (match_operand 1 "" "")))]
9766 "TARGET_POWERPC64"
9767 "@
9768 bctr
9769 {br|blr}"
9770 [(set_attr "type" "jmpreg")])
9771
1fd4e8c1
RK
9772(define_insn "nop"
9773 [(const_int 0)]
9774 ""
ca7f5001 9775 "{cror 0,0,0|nop}")
1fd4e8c1 9776\f
7e69e155 9777;; Define the subtract-one-and-jump insns, starting with the template
c225ba7b
RK
9778;; so loop.c knows what to generate.
9779
b6c9286a
MM
9780(define_expand "decrement_and_branch_on_count"
9781 [(parallel [(set (pc) (if_then_else (ne (match_operand:SI 0 "register_operand" "")
c225ba7b
RK
9782 (const_int 1))
9783 (label_ref (match_operand 1 "" ""))
9784 (pc)))
b6c9286a
MM
9785 (set (match_dup 0)
9786 (plus:SI (match_dup 0)
9787 (const_int -1)))
5f81043f
RK
9788 (clobber (match_scratch:CC 2 ""))
9789 (clobber (match_scratch:SI 3 ""))])]
c225ba7b
RK
9790 ""
9791 "")
9792
1fd4e8c1
RK
9793;; We need to be able to do this for any operand, including MEM, or we
9794;; will cause reload to blow up since we don't allow output reloads on
7e69e155 9795;; JUMP_INSNs.
5f81043f
RK
9796;; In order that the length attribute is calculated correctly, the
9797;; label MUST be operand 0.
9798
1fd4e8c1
RK
9799(define_insn ""
9800 [(set (pc)
5f81043f 9801 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,*r,*r")
1fd4e8c1 9802 (const_int 1))
a6845123 9803 (label_ref (match_operand 0 "" ""))
1fd4e8c1 9804 (pc)))
5f81043f
RK
9805 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
9806 (plus:SI (match_dup 1)
9807 (const_int -1)))
1fd4e8c1
RK
9808 (clobber (match_scratch:CC 3 "=X,&x,&x"))
9809 (clobber (match_scratch:SI 4 "=X,X,r"))]
9810 ""
b19003d8
RK
9811 "*
9812{
af87a13e 9813 if (which_alternative != 0)
b19003d8
RK
9814 return \"#\";
9815 else if (get_attr_length (insn) == 8)
a6845123 9816 return \"{bdn|bdnz} %l0\";
b19003d8 9817 else
c81bebd7 9818 return \"bdz %$+8\;b %l0\";
b19003d8 9819}"
baf97f86
RK
9820 [(set_attr "type" "branch")
9821 (set_attr "length" "*,12,16")])
7e69e155 9822
5f81043f
RK
9823(define_insn ""
9824 [(set (pc)
9825 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,*r,*r")
9826 (const_int 1))
9827 (pc)
9828 (label_ref (match_operand 0 "" ""))))
9829 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
9830 (plus:SI (match_dup 1)
9831 (const_int -1)))
9832 (clobber (match_scratch:CC 3 "=X,&x,&x"))
9833 (clobber (match_scratch:SI 4 "=X,X,r"))]
9834 ""
9835 "*
9836{
9837 if (which_alternative != 0)
9838 return \"#\";
9839 else if (get_attr_length (insn) == 8)
9840 return \"bdz %l0\";
9841 else
c81bebd7 9842 return \"{bdn|bdnz} %$+8\;b %l0\";
5f81043f
RK
9843}"
9844 [(set_attr "type" "branch")
9845 (set_attr "length" "*,12,16")])
9846
c225ba7b 9847;; Similar, but we can use GE since we have a REG_NONNEG.
1fd4e8c1
RK
9848(define_insn ""
9849 [(set (pc)
5f81043f 9850 (if_then_else (ge (match_operand:SI 1 "register_operand" "c,*r,*r")
1fd4e8c1 9851 (const_int 0))
a6845123 9852 (label_ref (match_operand 0 "" ""))
1fd4e8c1 9853 (pc)))
5f81043f
RK
9854 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
9855 (plus:SI (match_dup 1)
9856 (const_int -1)))
1fd4e8c1
RK
9857 (clobber (match_scratch:CC 3 "=X,&x,&X"))
9858 (clobber (match_scratch:SI 4 "=X,X,r"))]
9859 "find_reg_note (insn, REG_NONNEG, 0)"
b19003d8
RK
9860 "*
9861{
af87a13e 9862 if (which_alternative != 0)
b19003d8
RK
9863 return \"#\";
9864 else if (get_attr_length (insn) == 8)
a6845123 9865 return \"{bdn|bdnz} %l0\";
b19003d8 9866 else
c81bebd7 9867 return \"bdz %$+8\;b %l0\";
b19003d8 9868}"
baf97f86
RK
9869 [(set_attr "type" "branch")
9870 (set_attr "length" "*,12,16")])
7e69e155 9871
1fd4e8c1
RK
9872(define_insn ""
9873 [(set (pc)
5f81043f
RK
9874 (if_then_else (ge (match_operand:SI 1 "register_operand" "c,*r,*r")
9875 (const_int 0))
9876 (pc)
9877 (label_ref (match_operand 0 "" ""))))
9878 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
9879 (plus:SI (match_dup 1)
9880 (const_int -1)))
9881 (clobber (match_scratch:CC 3 "=X,&x,&X"))
9882 (clobber (match_scratch:SI 4 "=X,X,r"))]
9883 "find_reg_note (insn, REG_NONNEG, 0)"
9884 "*
9885{
9886 if (which_alternative != 0)
9887 return \"#\";
9888 else if (get_attr_length (insn) == 8)
9889 return \"bdz %l0\";
9890 else
c81bebd7 9891 return \"{bdn|bdnz} %$+8\;b %l0\";
5f81043f
RK
9892}"
9893 [(set_attr "type" "branch")
9894 (set_attr "length" "*,12,16")])
9895
9896(define_insn ""
9897 [(set (pc)
9898 (if_then_else (eq (match_operand:SI 1 "register_operand" "c,*r,*r")
1fd4e8c1 9899 (const_int 1))
a6845123 9900 (label_ref (match_operand 0 "" ""))
1fd4e8c1 9901 (pc)))
5f81043f
RK
9902 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
9903 (plus:SI (match_dup 1)
9904 (const_int -1)))
1fd4e8c1
RK
9905 (clobber (match_scratch:CC 3 "=X,&x,&x"))
9906 (clobber (match_scratch:SI 4 "=X,X,r"))]
9907 ""
b19003d8
RK
9908 "*
9909{
af87a13e 9910 if (which_alternative != 0)
b19003d8
RK
9911 return \"#\";
9912 else if (get_attr_length (insn) == 8)
a6845123 9913 return \"bdz %l0\";
b19003d8 9914 else
c81bebd7 9915 return \"{bdn|bdnz} %$+8\;b %l0\";
b19003d8 9916}"
baf97f86
RK
9917 [(set_attr "type" "branch")
9918 (set_attr "length" "*,12,16")])
1fd4e8c1 9919
5f81043f
RK
9920(define_insn ""
9921 [(set (pc)
9922 (if_then_else (eq (match_operand:SI 1 "register_operand" "c,*r,*r")
9923 (const_int 1))
9924 (pc)
9925 (label_ref (match_operand 0 "" ""))))
9926 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
9927 (plus:SI (match_dup 1)
9928 (const_int -1)))
9929 (clobber (match_scratch:CC 3 "=X,&x,&x"))
9930 (clobber (match_scratch:SI 4 "=X,X,r"))]
9931 ""
9932 "*
9933{
9934 if (which_alternative != 0)
9935 return \"#\";
9936 else if (get_attr_length (insn) == 8)
9937 return \"{bdn|bdnz} %l0\";
9938 else
c81bebd7 9939 return \"bdz %$+8\;b %l0\";
5f81043f
RK
9940}"
9941 [(set_attr "type" "branch")
9942 (set_attr "length" "*,12,16")])
9943
1fd4e8c1
RK
9944(define_split
9945 [(set (pc)
9946 (if_then_else (match_operator 2 "comparison_operator"
cd2b37d9 9947 [(match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1
RK
9948 (const_int 1)])
9949 (match_operand 5 "" "")
9950 (match_operand 6 "" "")))
cd2b37d9 9951 (set (match_operand:SI 0 "gpc_reg_operand" "")
5f81043f
RK
9952 (plus:SI (match_dup 1)
9953 (const_int -1)))
1fd4e8c1
RK
9954 (clobber (match_scratch:CC 3 ""))
9955 (clobber (match_scratch:SI 4 ""))]
9956 "reload_completed"
9957 [(parallel [(set (match_dup 3)
5f81043f
RK
9958 (compare:CC (plus:SI (match_dup 1)
9959 (const_int -1))
1fd4e8c1 9960 (const_int 0)))
5f81043f
RK
9961 (set (match_dup 0)
9962 (plus:SI (match_dup 1)
9963 (const_int -1)))])
9964 (set (pc) (if_then_else (match_dup 7)
9965 (match_dup 5)
9966 (match_dup 6)))]
1fd4e8c1
RK
9967 "
9968{ operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3],
9969 const0_rtx); }")
9970
9971(define_split
9972 [(set (pc)
9973 (if_then_else (match_operator 2 "comparison_operator"
cd2b37d9 9974 [(match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1
RK
9975 (const_int 1)])
9976 (match_operand 5 "" "")
9977 (match_operand 6 "" "")))
9978 (set (match_operand:SI 0 "general_operand" "")
9979 (plus:SI (match_dup 1) (const_int -1)))
9980 (clobber (match_scratch:CC 3 ""))
9981 (clobber (match_scratch:SI 4 ""))]
cd2b37d9 9982 "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
1fd4e8c1 9983 [(parallel [(set (match_dup 3)
5f81043f
RK
9984 (compare:CC (plus:SI (match_dup 1)
9985 (const_int -1))
1fd4e8c1 9986 (const_int 0)))
5f81043f
RK
9987 (set (match_dup 4)
9988 (plus:SI (match_dup 1)
9989 (const_int -1)))])
9990 (set (match_dup 0)
9991 (match_dup 4))
9992 (set (pc) (if_then_else (match_dup 7)
9993 (match_dup 5)
9994 (match_dup 6)))]
1fd4e8c1
RK
9995 "
9996{ operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3],
9997 const0_rtx); }")