]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/rs6000/rs6000.md
pa.c (emit_move_sequence): Don't lose for a secondary reload to the SAR register...
[thirdparty/gcc.git] / gcc / config / rs6000 / rs6000.md
CommitLineData
996a5f59 1;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
cf27b467 2;; Copyright (C) 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
996a5f59 3;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
1fd4e8c1
RK
4
5;; This file is part of GNU CC.
6
7;; GNU CC is free software; you can redistribute it and/or modify
8;; it under the terms of the GNU General Public License as published by
9;; the Free Software Foundation; either version 2, or (at your option)
10;; any later version.
11
12;; GNU CC is distributed in the hope that it will be useful,
13;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15;; GNU General Public License for more details.
16
17;; You should have received a copy of the GNU General Public License
18;; along with GNU CC; see the file COPYING. If not, write to
3f63df56
RK
19;; the Free Software Foundation, 59 Temple Place - Suite 330,
20;; Boston, MA 02111-1307, USA.
1fd4e8c1
RK
21
22;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
23\f
24;; Define an insn type attribute. This is used in function unit delay
25;; computations.
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.
f357808b 861(define_insn "addsi3"
deb9225a
RK
862 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,?r,r")
863 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "%r,b,r,b")
864 (match_operand:SI 2 "add_operand" "r,I,I,J")))]
1fd4e8c1
RK
865 ""
866 "@
deb9225a
RK
867 {cax|add} %0,%1,%2
868 {cal %0,%2(%1)|addi %0,%1,%2}
869 {ai|addic} %0,%1,%2
802a0058 870 {cau|addis} %0,%1,%v2")
1fd4e8c1
RK
871
872(define_insn ""
deb9225a
RK
873 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
874 (compare:CC (plus:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
875 (match_operand:SI 2 "reg_or_short_operand" "r,I"))
1fd4e8c1 876 (const_int 0)))
deb9225a 877 (clobber (match_scratch:SI 3 "=r,r"))]
1fd4e8c1 878 ""
deb9225a
RK
879 "@
880 {cax.|add.} %3,%1,%2
881 {ai.|addic.} %3,%1,%2"
1fd4e8c1 882 [(set_attr "type" "compare")])
7e69e155 883
1fd4e8c1 884(define_insn ""
deb9225a
RK
885 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
886 (compare:CC (plus:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
887 (match_operand:SI 2 "reg_or_short_operand" "r,I"))
1fd4e8c1 888 (const_int 0)))
deb9225a 889 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
890 (plus:SI (match_dup 1) (match_dup 2)))]
891 ""
deb9225a
RK
892 "@
893 {cax.|add.} %0,%1,%2
894 {ai.|addic.} %0,%1,%2"
1fd4e8c1 895 [(set_attr "type" "compare")])
7e69e155 896
f357808b
RK
897;; Split an add that we can't do in one insn into two insns, each of which
898;; does one 16-bit part. This is used by combine. Note that the low-order
899;; add should be last in case the result gets used in an address.
900
901(define_split
cd2b37d9
RK
902 [(set (match_operand:SI 0 "gpc_reg_operand" "")
903 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "")
f357808b 904 (match_operand:SI 2 "non_add_cint_operand" "")))]
1fd4e8c1 905 ""
f357808b
RK
906 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))
907 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))]
908"
1fd4e8c1 909{
e6ca2c17
DE
910 HOST_WIDE_INT low = INTVAL (operands[2]) & 0xffff;
911 HOST_WIDE_INT high = INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff);
1fd4e8c1 912
f357808b 913 if (low & 0x8000)
e6ca2c17 914 high += 0x10000, low |= ((HOST_WIDE_INT) -1) << 16;
1fd4e8c1 915
e6ca2c17
DE
916 operands[3] = GEN_INT (high);
917 operands[4] = GEN_INT (low);
1fd4e8c1
RK
918}")
919
8de2a197 920(define_insn "one_cmplsi2"
cd2b37d9
RK
921 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
922 (not:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
1fd4e8c1 923 ""
ca7f5001
RK
924 "nor %0,%1,%1")
925
926(define_insn ""
927 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
928 (compare:CC (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
929 (const_int 0)))
930 (clobber (match_scratch:SI 2 "=r"))]
931 ""
932 "nor. %2,%1,%1"
933 [(set_attr "type" "compare")])
934
935(define_insn ""
8de2a197 936 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
ca7f5001
RK
937 (compare:CC (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
938 (const_int 0)))
939 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
940 (not:SI (match_dup 1)))]
941 ""
d944f453 942 "nor. %0,%1,%1"
ca7f5001 943 [(set_attr "type" "compare")])
1fd4e8c1
RK
944
945(define_insn ""
3d91674b
RK
946 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
947 (minus:SI (match_operand:SI 1 "reg_or_short_operand" "rI")
948 (match_operand:SI 2 "gpc_reg_operand" "r")))]
deb9225a 949 "! TARGET_POWERPC"
ca7f5001 950 "{sf%I1|subf%I1c} %0,%2,%1")
1fd4e8c1 951
deb9225a
RK
952(define_insn ""
953 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
954 (minus:SI (match_operand:SI 1 "reg_or_short_operand" "r,I")
955 (match_operand:SI 2 "gpc_reg_operand" "r,r")))]
956 "TARGET_POWERPC"
957 "@
958 subf %0,%2,%1
959 subfic %0,%2,%1")
960
1fd4e8c1
RK
961(define_insn ""
962 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
cd2b37d9
RK
963 (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
964 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1
RK
965 (const_int 0)))
966 (clobber (match_scratch:SI 3 "=r"))]
deb9225a 967 "! TARGET_POWERPC"
ca7f5001 968 "{sf.|subfc.} %3,%2,%1"
1fd4e8c1
RK
969 [(set_attr "type" "compare")])
970
deb9225a
RK
971(define_insn ""
972 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
973 (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
974 (match_operand:SI 2 "gpc_reg_operand" "r"))
975 (const_int 0)))
976 (clobber (match_scratch:SI 3 "=r"))]
977 "TARGET_POWERPC"
978 "subf. %3,%2,%1"
979 [(set_attr "type" "compare")])
980
1fd4e8c1
RK
981(define_insn ""
982 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
cd2b37d9
RK
983 (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
984 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 985 (const_int 0)))
cd2b37d9 986 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1 987 (minus:SI (match_dup 1) (match_dup 2)))]
deb9225a 988 "! TARGET_POWERPC"
ca7f5001 989 "{sf.|subfc.} %0,%2,%1"
1fd4e8c1
RK
990 [(set_attr "type" "compare")])
991
deb9225a
RK
992(define_insn ""
993 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
994 (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
995 (match_operand:SI 2 "gpc_reg_operand" "r"))
996 (const_int 0)))
997 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
998 (minus:SI (match_dup 1) (match_dup 2)))]
999 "TARGET_POWERPC"
1000 "subf. %0,%2,%1"
1001 [(set_attr "type" "compare")])
1002
1fd4e8c1 1003(define_expand "subsi3"
cd2b37d9 1004 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
1005 (minus:SI (match_operand:SI 1 "reg_or_short_operand" "")
1006 (match_operand:SI 2 "reg_or_cint_operand" "")))]
1007 ""
a0044fb1
RK
1008 "
1009{
1010 if (GET_CODE (operands[2]) == CONST_INT)
1011 {
1012 emit_insn (gen_addsi3 (operands[0], operands[1],
1013 negate_rtx (SImode, operands[2])));
1014 DONE;
1015 }
1016}")
1fd4e8c1
RK
1017
1018;; For SMIN, SMAX, UMIN, and UMAX, we use DEFINE_EXPAND's that involve a doz[i]
1019;; instruction and some auxiliary computations. Then we just have a single
95ac8e67
RK
1020;; DEFINE_INSN for doz[i] and the define_splits to make them if made by
1021;; combine.
1fd4e8c1
RK
1022
1023(define_expand "sminsi3"
1024 [(set (match_dup 3)
cd2b37d9 1025 (if_then_else:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1
RK
1026 (match_operand:SI 2 "reg_or_short_operand" ""))
1027 (const_int 0)
1028 (minus:SI (match_dup 2) (match_dup 1))))
cd2b37d9 1029 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1 1030 (minus:SI (match_dup 2) (match_dup 3)))]
ca7f5001 1031 "TARGET_POWER"
1fd4e8c1
RK
1032 "
1033{ operands[3] = gen_reg_rtx (SImode); }")
1034
95ac8e67
RK
1035(define_split
1036 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1037 (smin:SI (match_operand:SI 1 "gpc_reg_operand" "")
1038 (match_operand:SI 2 "reg_or_short_operand" "")))
1039 (clobber (match_operand:SI 3 "gpc_reg_operand" ""))]
ca7f5001 1040 "TARGET_POWER"
95ac8e67
RK
1041 [(set (match_dup 3)
1042 (if_then_else:SI (gt:SI (match_dup 1) (match_dup 2))
1043 (const_int 0)
1044 (minus:SI (match_dup 2) (match_dup 1))))
1045 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 3)))]
1046 "")
1047
1fd4e8c1
RK
1048(define_expand "smaxsi3"
1049 [(set (match_dup 3)
cd2b37d9 1050 (if_then_else:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1
RK
1051 (match_operand:SI 2 "reg_or_short_operand" ""))
1052 (const_int 0)
1053 (minus:SI (match_dup 2) (match_dup 1))))
cd2b37d9 1054 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1 1055 (plus:SI (match_dup 3) (match_dup 1)))]
ca7f5001 1056 "TARGET_POWER"
1fd4e8c1
RK
1057 "
1058{ operands[3] = gen_reg_rtx (SImode); }")
1059
95ac8e67
RK
1060(define_split
1061 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1062 (smax:SI (match_operand:SI 1 "gpc_reg_operand" "")
1063 (match_operand:SI 2 "reg_or_short_operand" "")))
1064 (clobber (match_operand:SI 3 "gpc_reg_operand" ""))]
ca7f5001 1065 "TARGET_POWER"
95ac8e67
RK
1066 [(set (match_dup 3)
1067 (if_then_else:SI (gt:SI (match_dup 1) (match_dup 2))
1068 (const_int 0)
1069 (minus:SI (match_dup 2) (match_dup 1))))
1070 (set (match_dup 0) (plus:SI (match_dup 3) (match_dup 1)))]
1071 "")
1072
1fd4e8c1 1073(define_expand "uminsi3"
cd2b37d9 1074 [(set (match_dup 3) (xor:SI (match_operand:SI 1 "gpc_reg_operand" "")
bb68ff55 1075 (match_dup 5)))
cd2b37d9 1076 (set (match_dup 4) (xor:SI (match_operand:SI 2 "gpc_reg_operand" "")
bb68ff55 1077 (match_dup 5)))
1fd4e8c1
RK
1078 (set (match_dup 3) (if_then_else:SI (gt (match_dup 3) (match_dup 4))
1079 (const_int 0)
1080 (minus:SI (match_dup 4) (match_dup 3))))
cd2b37d9 1081 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1 1082 (minus:SI (match_dup 2) (match_dup 3)))]
ca7f5001 1083 "TARGET_POWER"
1fd4e8c1 1084 "
bb68ff55
MM
1085{
1086 operands[3] = gen_reg_rtx (SImode);
1087 operands[4] = gen_reg_rtx (SImode);
1088 operands[5] = GEN_INT (-2147483647 - 1);
1089}")
1fd4e8c1
RK
1090
1091(define_expand "umaxsi3"
cd2b37d9 1092 [(set (match_dup 3) (xor:SI (match_operand:SI 1 "gpc_reg_operand" "")
bb68ff55 1093 (match_dup 5)))
cd2b37d9 1094 (set (match_dup 4) (xor:SI (match_operand:SI 2 "gpc_reg_operand" "")
bb68ff55 1095 (match_dup 5)))
1fd4e8c1
RK
1096 (set (match_dup 3) (if_then_else:SI (gt (match_dup 3) (match_dup 4))
1097 (const_int 0)
1098 (minus:SI (match_dup 4) (match_dup 3))))
cd2b37d9 1099 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1 1100 (plus:SI (match_dup 3) (match_dup 1)))]
ca7f5001 1101 "TARGET_POWER"
1fd4e8c1 1102 "
bb68ff55
MM
1103{
1104 operands[3] = gen_reg_rtx (SImode);
1105 operands[4] = gen_reg_rtx (SImode);
1106 operands[5] = GEN_INT (-2147483647 - 1);
1107}")
1fd4e8c1
RK
1108
1109(define_insn ""
cd2b37d9
RK
1110 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1111 (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "r")
5c23c401 1112 (match_operand:SI 2 "reg_or_short_operand" "rI"))
1fd4e8c1
RK
1113 (const_int 0)
1114 (minus:SI (match_dup 2) (match_dup 1))))]
ca7f5001 1115 "TARGET_POWER"
1fd4e8c1
RK
1116 "doz%I2 %0,%1,%2")
1117
1118(define_insn ""
1119 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1120 (compare:CC
cd2b37d9 1121 (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "r")
5c23c401 1122 (match_operand:SI 2 "reg_or_short_operand" "rI"))
1fd4e8c1
RK
1123 (const_int 0)
1124 (minus:SI (match_dup 2) (match_dup 1)))
1125 (const_int 0)))
1126 (clobber (match_scratch:SI 3 "=r"))]
ca7f5001 1127 "TARGET_POWER"
1fd4e8c1
RK
1128 "doz%I2. %3,%1,%2"
1129 [(set_attr "type" "delayed_compare")])
1130
1131(define_insn ""
1132 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1133 (compare:CC
cd2b37d9 1134 (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "r")
5c23c401 1135 (match_operand:SI 2 "reg_or_short_operand" "rI"))
1fd4e8c1
RK
1136 (const_int 0)
1137 (minus:SI (match_dup 2) (match_dup 1)))
1138 (const_int 0)))
cd2b37d9 1139 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
1140 (if_then_else:SI (gt (match_dup 1) (match_dup 2))
1141 (const_int 0)
1142 (minus:SI (match_dup 2) (match_dup 1))))]
ca7f5001 1143 "TARGET_POWER"
1fd4e8c1
RK
1144 "doz%I2. %0,%1,%2"
1145 [(set_attr "type" "delayed_compare")])
1146
1147;; We don't need abs with condition code because such comparisons should
1148;; never be done.
ea9be077
MM
1149(define_expand "abssi2"
1150 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1151 (abs:SI (match_operand:SI 1 "gpc_reg_operand" "")))]
1152 ""
1153 "
1154{
1155 if (!TARGET_POWER)
1156 {
1157 emit_insn (gen_abssi2_nopower (operands[0], operands[1]));
1158 DONE;
1159 }
1160}")
1161
1162(define_insn "abssi2_power"
cd2b37d9
RK
1163 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1164 (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
ca7f5001 1165 "TARGET_POWER"
1fd4e8c1
RK
1166 "abs %0,%1")
1167
ea9be077
MM
1168(define_insn "abssi2_nopower"
1169 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r")
1170 (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0")))
1171 (clobber (match_scratch:SI 2 "=&r,&r"))]
1172 "!TARGET_POWER"
3595d104
MM
1173 "*
1174{
1175 return (TARGET_POWERPC)
1176 ? \"{srai|srawi} %2,%1,31\;xor %0,%2,%1\;subf %0,%2,%0\"
1177 : \"{srai|srawi} %2,%1,31\;xor %0,%2,%1\;{sf|subfc} %0,%2,%0\";
1178}"
ea9be077
MM
1179 [(set_attr "length" "12")])
1180
1181(define_split
1182 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r")
1183 (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0")))
1184 (clobber (match_scratch:SI 2 "=&r,&r"))]
1185 "!TARGET_POWER && reload_completed"
1186 [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31)))
1187 (set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))
1188 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 0)))]
1189 "")
1190
1fd4e8c1 1191(define_insn ""
cd2b37d9
RK
1192 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1193 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r"))))]
ca7f5001 1194 "TARGET_POWER"
1fd4e8c1
RK
1195 "nabs %0,%1")
1196
ea9be077
MM
1197(define_insn ""
1198 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r")
1199 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0"))))
1200 (clobber (match_scratch:SI 2 "=&r,&r"))]
1201 "!TARGET_POWER"
3595d104
MM
1202 "*
1203{
1204 return (TARGET_POWERPC)
1205 ? \"{srai|srawi} %2,%1,31\;xor %0,%2,%1\;subf %0,%0,%2\"
1206 : \"{srai|srawi} %2,%1,31\;xor %0,%2,%1\;{sf|subfc} %0,%0,%2\";
1207}"
ea9be077
MM
1208 [(set_attr "length" "12")])
1209
1210(define_split
1211 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r")
1212 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0"))))
1213 (clobber (match_scratch:SI 2 "=&r,&r"))]
1214 "!TARGET_POWER && reload_completed"
1215 [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31)))
1216 (set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))
1217 (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 2)))]
1218 "")
1219
1fd4e8c1 1220(define_insn "negsi2"
cd2b37d9
RK
1221 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1222 (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
1fd4e8c1
RK
1223 ""
1224 "neg %0,%1")
1225
1226(define_insn ""
1227 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
cd2b37d9 1228 (compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1fd4e8c1
RK
1229 (const_int 0)))
1230 (clobber (match_scratch:SI 2 "=r"))]
1231 ""
1232 "neg. %2,%1"
1233 [(set_attr "type" "compare")])
1234
1235(define_insn ""
1236 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
cd2b37d9 1237 (compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1fd4e8c1 1238 (const_int 0)))
cd2b37d9 1239 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
1240 (neg:SI (match_dup 1)))]
1241 ""
1242 "neg. %0,%1"
1243 [(set_attr "type" "compare")])
1244
1245(define_insn "ffssi2"
242e8072
RK
1246 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r")
1247 (ffs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
1fd4e8c1 1248 ""
7f340546 1249 "neg %0,%1\;and %0,%0,%1\;{cntlz|cntlzw} %0,%0\;{sfi|subfic} %0,%0,32"
b19003d8 1250 [(set_attr "length" "16")])
1fd4e8c1 1251
ca7f5001
RK
1252(define_expand "mulsi3"
1253 [(use (match_operand:SI 0 "gpc_reg_operand" ""))
1254 (use (match_operand:SI 1 "gpc_reg_operand" ""))
1255 (use (match_operand:SI 2 "reg_or_short_operand" ""))]
1256 ""
1257 "
1258{
1259 if (TARGET_POWER)
68b40e7e 1260 emit_insn (gen_mulsi3_mq (operands[0], operands[1], operands[2]));
ca7f5001 1261 else
68b40e7e 1262 emit_insn (gen_mulsi3_no_mq (operands[0], operands[1], operands[2]));
ca7f5001
RK
1263 DONE;
1264}")
1265
68b40e7e 1266(define_insn "mulsi3_mq"
cd2b37d9
RK
1267 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1268 (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
1fd4e8c1
RK
1269 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
1270 (clobber (match_scratch:SI 3 "=q,q"))]
ca7f5001
RK
1271 "TARGET_POWER"
1272 "@
1273 {muls|mullw} %0,%1,%2
1274 {muli|mulli} %0,%1,%2"
1275 [(set_attr "type" "imul")])
1276
68b40e7e 1277(define_insn "mulsi3_no_mq"
ca7f5001
RK
1278 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1279 (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
1280 (match_operand:SI 2 "reg_or_short_operand" "r,I")))]
68b40e7e 1281 "! TARGET_POWER"
1fd4e8c1 1282 "@
d904e9ed
RK
1283 {muls|mullw} %0,%1,%2
1284 {muli|mulli} %0,%1,%2"
cfb557c4 1285 [(set_attr "type" "imul")])
1fd4e8c1
RK
1286
1287(define_insn ""
1288 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
deb9225a 1289 (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
cd2b37d9 1290 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1
RK
1291 (const_int 0)))
1292 (clobber (match_scratch:SI 3 "=r"))
1293 (clobber (match_scratch:SI 4 "=q"))]
ca7f5001
RK
1294 "TARGET_POWER"
1295 "{muls.|mullw.} %3,%1,%2"
1296 [(set_attr "type" "delayed_compare")])
1297
1298(define_insn ""
1299 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
deb9225a 1300 (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
ca7f5001
RK
1301 (match_operand:SI 2 "gpc_reg_operand" "r"))
1302 (const_int 0)))
1303 (clobber (match_scratch:SI 3 "=r"))]
25c341fa 1304 "! TARGET_POWER"
d904e9ed 1305 "{muls.|mullw.} %3,%1,%2"
1fd4e8c1
RK
1306 [(set_attr "type" "delayed_compare")])
1307
1308(define_insn ""
1309 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
deb9225a 1310 (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
cd2b37d9 1311 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 1312 (const_int 0)))
cd2b37d9 1313 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
1314 (mult:SI (match_dup 1) (match_dup 2)))
1315 (clobber (match_scratch:SI 4 "=q"))]
ca7f5001
RK
1316 "TARGET_POWER"
1317 "{muls.|mullw.} %0,%1,%2"
1318 [(set_attr "type" "delayed_compare")])
1319
1320(define_insn ""
1321 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
deb9225a 1322 (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
ca7f5001
RK
1323 (match_operand:SI 2 "gpc_reg_operand" "r"))
1324 (const_int 0)))
1325 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1326 (mult:SI (match_dup 1) (match_dup 2)))]
25c341fa 1327 "! TARGET_POWER"
d904e9ed 1328 "{muls.|mullw.} %0,%1,%2"
1fd4e8c1
RK
1329 [(set_attr "type" "delayed_compare")])
1330
1331;; Operand 1 is divided by operand 2; quotient goes to operand
1332;; 0 and remainder to operand 3.
1333;; ??? At some point, see what, if anything, we can do about if (x % y == 0).
1334
8ffd9c51
RK
1335(define_expand "divmodsi4"
1336 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
1337 (div:SI (match_operand:SI 1 "gpc_reg_operand" "")
1338 (match_operand:SI 2 "gpc_reg_operand" "")))
1339 (set (match_operand:SI 3 "gpc_reg_operand" "")
1340 (mod:SI (match_dup 1) (match_dup 2)))])]
1341 "TARGET_POWER || (! TARGET_POWER && ! TARGET_POWERPC)"
1342 "
1343{
1344 if (! TARGET_POWER && ! TARGET_POWERPC)
1345 {
1346 emit_move_insn (gen_rtx (REG, SImode, 3), operands[1]);
1347 emit_move_insn (gen_rtx (REG, SImode, 4), operands[2]);
fada905b 1348 emit_insn (gen_divss_call ());
8ffd9c51
RK
1349 emit_move_insn (operands[0], gen_rtx (REG, SImode, 3));
1350 emit_move_insn (operands[3], gen_rtx (REG, SImode, 4));
1351 DONE;
1352 }
1353}")
deb9225a 1354
fada905b 1355(define_insn ""
cd2b37d9
RK
1356 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1357 (div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1358 (match_operand:SI 2 "gpc_reg_operand" "r")))
1359 (set (match_operand:SI 3 "gpc_reg_operand" "=q")
1fd4e8c1 1360 (mod:SI (match_dup 1) (match_dup 2)))]
ca7f5001 1361 "TARGET_POWER"
cfb557c4
RK
1362 "divs %0,%1,%2"
1363 [(set_attr "type" "idiv")])
1fd4e8c1 1364
fada905b 1365(define_insn ""
ca7f5001
RK
1366 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1367 (div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1368 (match_operand:SI 2 "gpc_reg_operand" "r")))]
1369 "TARGET_POWERPC"
a473029f 1370 "divw %0,%1,%2"
ca7f5001
RK
1371 [(set_attr "type" "idiv")])
1372
8ffd9c51
RK
1373(define_expand "udivsi3"
1374 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1375 (udiv:SI (match_operand:SI 1 "gpc_reg_operand" "")
1376 (match_operand:SI 2 "gpc_reg_operand" "")))]
1377 "TARGET_POWERPC || (! TARGET_POWER && ! TARGET_POWERPC)"
1378 "
1379{
1380 if (! TARGET_POWER && ! TARGET_POWERPC)
1381 {
1382 emit_move_insn (gen_rtx (REG, SImode, 3), operands[1]);
1383 emit_move_insn (gen_rtx (REG, SImode, 4), operands[2]);
fada905b 1384 emit_insn (gen_quous_call ());
8ffd9c51
RK
1385 emit_move_insn (operands[0], gen_rtx (REG, SImode, 3));
1386 DONE;
1387 }
1388}")
deb9225a 1389
fada905b 1390(define_insn ""
ca7f5001
RK
1391 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1392 (udiv:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1393 (match_operand:SI 2 "gpc_reg_operand" "r")))]
1394 "TARGET_POWERPC"
a473029f 1395 "divwu %0,%1,%2"
ca7f5001
RK
1396 [(set_attr "type" "idiv")])
1397
1fd4e8c1 1398;; For powers of two we can do srai/aze for divide and then adjust for
ca7f5001 1399;; modulus. If it isn't a power of two, FAIL on POWER so divmodsi4 will be
8ffd9c51
RK
1400;; used; for PowerPC, force operands into register and do a normal divide;
1401;; for AIX common-mode, use quoss call on register operands.
1fd4e8c1 1402(define_expand "divsi3"
cd2b37d9
RK
1403 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1404 (div:SI (match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1
RK
1405 (match_operand:SI 2 "reg_or_cint_operand" "")))]
1406 ""
1407 "
1408{
ca7f5001
RK
1409 if (GET_CODE (operands[2]) == CONST_INT
1410 && exact_log2 (INTVAL (operands[2])) >= 0)
1411 ;
b6c9286a
MM
1412 else if (TARGET_POWERPC)
1413 operands[2] = force_reg (SImode, operands[2]);
1414 else if (TARGET_POWER)
1fd4e8c1 1415 FAIL;
405c5495 1416 else
8ffd9c51
RK
1417 {
1418 emit_move_insn (gen_rtx (REG, SImode, 3), operands[1]);
1419 emit_move_insn (gen_rtx (REG, SImode, 4), operands[2]);
fada905b 1420 emit_insn (gen_quoss_call ());
8ffd9c51
RK
1421 emit_move_insn (operands[0], gen_rtx (REG, SImode, 3));
1422 DONE;
1423 }
1fd4e8c1
RK
1424}")
1425
1426(define_expand "modsi3"
85644414
RK
1427 [(use (match_operand:SI 0 "gpc_reg_operand" ""))
1428 (use (match_operand:SI 1 "gpc_reg_operand" ""))
405c5495 1429 (use (match_operand:SI 2 "reg_or_cint_operand" ""))]
39b52ba2 1430 ""
1fd4e8c1
RK
1431 "
1432{
39b52ba2
RK
1433 int i = exact_log2 (INTVAL (operands[2]));
1434 rtx temp1;
1435 rtx temp2;
1436
405c5495 1437 if (GET_CODE (operands[2]) != CONST_INT || i < 0)
39b52ba2
RK
1438 FAIL;
1439
1440 temp1 = gen_reg_rtx (SImode);
1441 temp2 = gen_reg_rtx (SImode);
1fd4e8c1 1442
85644414 1443 emit_insn (gen_divsi3 (temp1, operands[1], operands[2]));
39b52ba2 1444 emit_insn (gen_ashlsi3 (temp2, temp1, GEN_INT (i)));
85644414
RK
1445 emit_insn (gen_subsi3 (operands[0], operands[1], temp2));
1446 DONE;
1fd4e8c1
RK
1447}")
1448
1449(define_insn ""
cd2b37d9
RK
1450 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1451 (div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
1452 (match_operand:SI 2 "const_int_operand" "N")))]
1453 "exact_log2 (INTVAL (operands[2])) >= 0"
ca7f5001 1454 "{srai|srawi} %0,%1,%p2\;{aze|addze} %0,%0"
b19003d8 1455 [(set_attr "length" "8")])
1fd4e8c1
RK
1456
1457(define_insn ""
1458 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
b6b12107
RK
1459 (compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1460 (match_operand:SI 2 "const_int_operand" "N"))
1461 (const_int 0)))
1fd4e8c1
RK
1462 (clobber (match_scratch:SI 3 "=r"))]
1463 "exact_log2 (INTVAL (operands[2])) >= 0"
ca7f5001 1464 "{srai|srawi} %3,%1,%p2\;{aze.|addze.} %3,%3"
b19003d8
RK
1465 [(set_attr "type" "compare")
1466 (set_attr "length" "8")])
1fd4e8c1
RK
1467
1468(define_insn ""
1469 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
b6b12107
RK
1470 (compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1471 (match_operand:SI 2 "const_int_operand" "N"))
1472 (const_int 0)))
cd2b37d9 1473 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
1474 (div:SI (match_dup 1) (match_dup 2)))]
1475 "exact_log2 (INTVAL (operands[2])) >= 0"
ca7f5001 1476 "{srai|srawi} %0,%1,%p2\;{aze.|addze.} %0,%0"
b19003d8
RK
1477 [(set_attr "type" "compare")
1478 (set_attr "length" "8")])
1fd4e8c1
RK
1479
1480(define_insn ""
cd2b37d9 1481 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1 1482 (udiv:SI
996a5f59 1483 (plus:DI (ashift:DI
cd2b37d9 1484 (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
1fd4e8c1 1485 (const_int 32))
23a900dc 1486 (zero_extend:DI (match_operand:SI 4 "register_operand" "2")))
cd2b37d9 1487 (match_operand:SI 3 "gpc_reg_operand" "r")))
740ab4a2 1488 (set (match_operand:SI 2 "register_operand" "=*q")
1fd4e8c1 1489 (umod:SI
996a5f59 1490 (plus:DI (ashift:DI
1fd4e8c1 1491 (zero_extend:DI (match_dup 1)) (const_int 32))
740ab4a2 1492 (zero_extend:DI (match_dup 4)))
1fd4e8c1 1493 (match_dup 3)))]
ca7f5001 1494 "TARGET_POWER"
cfb557c4
RK
1495 "div %0,%1,%3"
1496 [(set_attr "type" "idiv")])
1fd4e8c1
RK
1497
1498;; To do unsigned divide we handle the cases of the divisor looking like a
1499;; negative number. If it is a constant that is less than 2**31, we don't
1500;; have to worry about the branches. So make a few subroutines here.
1501;;
1502;; First comes the normal case.
1503(define_expand "udivmodsi4_normal"
1504 [(set (match_dup 4) (const_int 0))
1505 (parallel [(set (match_operand:SI 0 "" "")
996a5f59 1506 (udiv:SI (plus:DI (ashift:DI (zero_extend:DI (match_dup 4))
1fd4e8c1
RK
1507 (const_int 32))
1508 (zero_extend:DI (match_operand:SI 1 "" "")))
1509 (match_operand:SI 2 "" "")))
1510 (set (match_operand:SI 3 "" "")
996a5f59 1511 (umod:SI (plus:DI (ashift:DI (zero_extend:DI (match_dup 4))
1fd4e8c1
RK
1512 (const_int 32))
1513 (zero_extend:DI (match_dup 1)))
1514 (match_dup 2)))])]
ca7f5001 1515 "TARGET_POWER"
1fd4e8c1
RK
1516 "
1517{ operands[4] = gen_reg_rtx (SImode); }")
1518
1519;; This handles the branches.
1520(define_expand "udivmodsi4_tests"
1521 [(set (match_operand:SI 0 "" "") (const_int 0))
1522 (set (match_operand:SI 3 "" "") (match_operand:SI 1 "" ""))
1523 (set (match_dup 5) (compare:CCUNS (match_dup 1) (match_operand:SI 2 "" "")))
1524 (set (pc) (if_then_else (ltu (match_dup 5) (const_int 0))
1525 (label_ref (match_operand:SI 4 "" "")) (pc)))
1526 (set (match_dup 0) (const_int 1))
1527 (set (match_dup 3) (minus:SI (match_dup 1) (match_dup 2)))
1528 (set (match_dup 6) (compare:CC (match_dup 2) (const_int 0)))
1529 (set (pc) (if_then_else (lt (match_dup 6) (const_int 0))
1530 (label_ref (match_dup 4)) (pc)))]
ca7f5001 1531 "TARGET_POWER"
1fd4e8c1
RK
1532 "
1533{ operands[5] = gen_reg_rtx (CCUNSmode);
1534 operands[6] = gen_reg_rtx (CCmode);
1535}")
1536
1537(define_expand "udivmodsi4"
cd2b37d9
RK
1538 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
1539 (udiv:SI (match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1 1540 (match_operand:SI 2 "reg_or_cint_operand" "")))
cd2b37d9 1541 (set (match_operand:SI 3 "gpc_reg_operand" "")
1fd4e8c1 1542 (umod:SI (match_dup 1) (match_dup 2)))])]
8ffd9c51 1543 ""
1fd4e8c1
RK
1544 "
1545{
1546 rtx label = 0;
1547
8ffd9c51
RK
1548 if (! TARGET_POWER)
1549 if (! TARGET_POWERPC)
1550 {
1551 emit_move_insn (gen_rtx (REG, SImode, 3), operands[1]);
1552 emit_move_insn (gen_rtx (REG, SImode, 4), operands[2]);
fada905b 1553 emit_insn (gen_divus_call ());
8ffd9c51
RK
1554 emit_move_insn (operands[0], gen_rtx (REG, SImode, 3));
1555 emit_move_insn (operands[3], gen_rtx (REG, SImode, 4));
1556 DONE;
1557 }
1558 else
1559 FAIL;
0081a354 1560
1fd4e8c1
RK
1561 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) < 0)
1562 {
1563 operands[2] = force_reg (SImode, operands[2]);
1564 label = gen_label_rtx ();
1565 emit (gen_udivmodsi4_tests (operands[0], operands[1], operands[2],
1566 operands[3], label));
1567 }
1568 else
1569 operands[2] = force_reg (SImode, operands[2]);
1570
1571 emit (gen_udivmodsi4_normal (operands[0], operands[1], operands[2],
1572 operands[3]));
1573 if (label)
1574 emit_label (label);
1575
1576 DONE;
1577}")
0081a354 1578
fada905b
MM
1579;; AIX architecture-independent common-mode multiply (DImode),
1580;; divide/modulus, and quotient subroutine calls. Input operands in R3 and
1581;; R4; results in R3 and sometimes R4; link register always clobbered by bla
1582;; instruction; R0 sometimes clobbered; also, MQ sometimes clobbered but
1583;; assumed unused if generating common-mode, so ignore.
1584(define_insn "mulh_call"
1585 [(set (reg:SI 3)
1586 (truncate:SI
1587 (lshiftrt:DI (mult:DI (sign_extend:DI (reg:SI 3))
1588 (sign_extend:DI (reg:SI 4)))
1589 (const_int 32))))
cf27b467 1590 (clobber (match_scratch:SI 0 "=l"))]
fada905b 1591 "! TARGET_POWER && ! TARGET_POWERPC"
b7ff3d82
DE
1592 "bla __mulh"
1593 [(set_attr "type" "imul")])
fada905b
MM
1594
1595(define_insn "mull_call"
1596 [(set (reg:DI 3)
1597 (mult:DI (sign_extend:DI (reg:SI 3))
1598 (sign_extend:DI (reg:SI 4))))
1599 (clobber (match_scratch:SI 0 "=l"))
1600 (clobber (reg:SI 0))]
1601 "! TARGET_POWER && ! TARGET_POWERPC"
b7ff3d82
DE
1602 "bla __mull"
1603 [(set_attr "type" "imul")])
fada905b
MM
1604
1605(define_insn "divss_call"
1606 [(set (reg:SI 3)
1607 (div:SI (reg:SI 3) (reg:SI 4)))
1608 (set (reg:SI 4)
1609 (mod:SI (reg:SI 3) (reg:SI 4)))
1610 (clobber (match_scratch:SI 0 "=l"))
1611 (clobber (reg:SI 0))]
1612 "! TARGET_POWER && ! TARGET_POWERPC"
b7ff3d82
DE
1613 "bla __divss"
1614 [(set_attr "type" "idiv")])
fada905b
MM
1615
1616(define_insn "divus_call"
8ffd9c51
RK
1617 [(set (reg:SI 3)
1618 (udiv:SI (reg:SI 3) (reg:SI 4)))
1619 (set (reg:SI 4)
1620 (umod:SI (reg:SI 3) (reg:SI 4)))
1621 (clobber (match_scratch:SI 0 "=l"))
fada905b
MM
1622 (clobber (reg:SI 0))
1623 (clobber (match_scratch:CC 1 "=x"))
1624 (clobber (reg:CC 69))]
1625 "! TARGET_POWER && ! TARGET_POWERPC"
b7ff3d82
DE
1626 "bla __divus"
1627 [(set_attr "type" "idiv")])
fada905b
MM
1628
1629(define_insn "quoss_call"
1630 [(set (reg:SI 3)
1631 (div:SI (reg:SI 3) (reg:SI 4)))
cf27b467 1632 (clobber (match_scratch:SI 0 "=l"))]
8ffd9c51 1633 "! TARGET_POWER && ! TARGET_POWERPC"
b7ff3d82
DE
1634 "bla __quoss"
1635 [(set_attr "type" "idiv")])
0081a354 1636
fada905b
MM
1637(define_insn "quous_call"
1638 [(set (reg:SI 3)
1639 (udiv:SI (reg:SI 3) (reg:SI 4)))
1640 (clobber (match_scratch:SI 0 "=l"))
1641 (clobber (reg:SI 0))
1642 (clobber (match_scratch:CC 1 "=x"))
1643 (clobber (reg:CC 69))]
1644 "! TARGET_POWER && ! TARGET_POWERPC"
b7ff3d82
DE
1645 "bla __quous"
1646 [(set_attr "type" "idiv")])
8ffd9c51 1647\f
1fd4e8c1 1648(define_insn "andsi3"
cd2b37d9
RK
1649 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
1650 (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r")
1fd4e8c1
RK
1651 (match_operand:SI 2 "and_operand" "?r,L,K,J")))
1652 (clobber (match_scratch:CC 3 "=X,X,x,x"))]
1653 ""
1654 "@
1655 and %0,%1,%2
ca7f5001
RK
1656 {rlinm|rlwinm} %0,%1,0,%m2,%M2
1657 {andil.|andi.} %0,%1,%b2
1658 {andiu.|andis.} %0,%1,%u2")
1fd4e8c1
RK
1659
1660(define_insn ""
1661 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x")
cd2b37d9 1662 (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r")
1fd4e8c1
RK
1663 (match_operand:SI 2 "and_operand" "r,K,J,L"))
1664 (const_int 0)))
1665 (clobber (match_scratch:SI 3 "=r,r,r,r"))]
1666 ""
1667 "@
1668 and. %3,%1,%2
ca7f5001
RK
1669 {andil.|andi.} %3,%1,%b2
1670 {andiu.|andis.} %3,%1,%u2
1671 {rlinm.|rlwinm.} %3,%1,0,%m2,%M2"
1fd4e8c1
RK
1672 [(set_attr "type" "compare,compare,compare,delayed_compare")])
1673
1674(define_insn ""
1675 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x")
cd2b37d9 1676 (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r")
1fd4e8c1
RK
1677 (match_operand:SI 2 "and_operand" "r,K,J,L"))
1678 (const_int 0)))
cd2b37d9 1679 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
1fd4e8c1
RK
1680 (and:SI (match_dup 1) (match_dup 2)))]
1681 ""
1682 "@
1683 and. %0,%1,%2
ca7f5001
RK
1684 {andil.|andi.} %0,%1,%b2
1685 {andiu.|andis.} %0,%1,%u2
1686 {rlinm.|rlwinm.} %0,%1,0,%m2,%M2"
b19003d8 1687 [(set_attr "type" "compare,compare,compare,delayed_compare")])
1fd4e8c1 1688
f357808b
RK
1689;; Take a AND with a constant that cannot be done in a single insn and try to
1690;; split it into two insns. This does not verify that the insns are valid
1691;; since this need not be done as combine will do it.
1692
1693(define_split
cd2b37d9
RK
1694 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1695 (and:SI (match_operand:SI 1 "gpc_reg_operand" "")
f357808b
RK
1696 (match_operand:SI 2 "non_and_cint_operand" "")))]
1697 ""
1698 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 3)))
1699 (set (match_dup 0) (and:SI (match_dup 0) (match_dup 4)))]
1700 "
1701{
1702 int maskval = INTVAL (operands[2]);
1703 int i, transitions, last_bit_value;
1704 int orig = maskval, first_c = maskval, second_c;
1705
1706 /* We know that MASKVAL must have more than 2 bit-transitions. Start at
1707 the low-order bit and count for the third transition. When we get there,
1708 make a first mask that has everything to the left of that position
1709 a one. Then make the second mask to turn off whatever else is needed. */
1710
1711 for (i = 1, transitions = 0, last_bit_value = maskval & 1; i < 32; i++)
1712 {
1713 if (((maskval >>= 1) & 1) != last_bit_value)
1714 last_bit_value ^= 1, transitions++;
1715
1716 if (transitions > 2)
1717 {
1718 first_c |= (~0) << i;
1719 break;
1720 }
1721 }
1722
1723 second_c = orig | ~ first_c;
1724
1725 operands[3] = gen_rtx (CONST_INT, VOIDmode, first_c);
1726 operands[4] = gen_rtx (CONST_INT, VOIDmode, second_c);
1727}")
1728
1729(define_insn "iorsi3"
cd2b37d9
RK
1730 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
1731 (ior:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r")
1fd4e8c1
RK
1732 (match_operand:SI 2 "logical_operand" "r,K,J")))]
1733 ""
1734 "@
1735 or %0,%1,%2
ca7f5001
RK
1736 {oril|ori} %0,%1,%b2
1737 {oriu|oris} %0,%1,%u2")
1fd4e8c1
RK
1738
1739(define_insn ""
1740 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
deb9225a 1741 (compare:CC (ior:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
cd2b37d9 1742 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1
RK
1743 (const_int 0)))
1744 (clobber (match_scratch:SI 3 "=r"))]
1745 ""
1746 "or. %3,%1,%2"
1747 [(set_attr "type" "compare")])
1748
1749(define_insn ""
1750 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
deb9225a 1751 (compare:CC (ior:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
cd2b37d9 1752 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 1753 (const_int 0)))
cd2b37d9 1754 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
1755 (ior:SI (match_dup 1) (match_dup 2)))]
1756 ""
1757 "or. %0,%1,%2"
1758 [(set_attr "type" "compare")])
1759
f357808b
RK
1760;; Split an IOR that we can't do in one insn into two insns, each of which
1761;; does one 16-bit part. This is used by combine.
1762
1763(define_split
cd2b37d9
RK
1764 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1765 (ior:SI (match_operand:SI 1 "gpc_reg_operand" "")
f357808b 1766 (match_operand:SI 2 "non_logical_cint_operand" "")))]
1fd4e8c1 1767 ""
f357808b
RK
1768 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))
1769 (set (match_dup 0) (ior:SI (match_dup 0) (match_dup 4)))]
1770"
1fd4e8c1 1771{
f357808b
RK
1772 operands[3] = gen_rtx (CONST_INT, VOIDmode,
1773 INTVAL (operands[2]) & 0xffff0000);
1774 operands[4] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0xffff);
1fd4e8c1
RK
1775}")
1776
f357808b 1777(define_insn "xorsi3"
cd2b37d9
RK
1778 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
1779 (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r")
1fd4e8c1
RK
1780 (match_operand:SI 2 "logical_operand" "r,K,J")))]
1781 ""
1782 "@
1783 xor %0,%1,%2
ca7f5001
RK
1784 {xoril|xori} %0,%1,%b2
1785 {xoriu|xoris} %0,%1,%u2")
1fd4e8c1
RK
1786
1787(define_insn ""
1788 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
deb9225a 1789 (compare:CC (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
cd2b37d9 1790 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1
RK
1791 (const_int 0)))
1792 (clobber (match_scratch:SI 3 "=r"))]
1793 ""
1794 "xor. %3,%1,%2"
1795 [(set_attr "type" "compare")])
1796
1797(define_insn ""
1798 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
deb9225a 1799 (compare:CC (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
cd2b37d9 1800 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 1801 (const_int 0)))
cd2b37d9 1802 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
1803 (xor:SI (match_dup 1) (match_dup 2)))]
1804 ""
1805 "xor. %0,%1,%2"
1806 [(set_attr "type" "compare")])
1807
f357808b
RK
1808;; Split an XOR that we can't do in one insn into two insns, each of which
1809;; does one 16-bit part. This is used by combine.
1810
1811(define_split
cd2b37d9
RK
1812 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1813 (xor:SI (match_operand:SI 1 "gpc_reg_operand" "")
f357808b 1814 (match_operand:SI 2 "non_logical_cint_operand" "")))]
1fd4e8c1 1815 ""
f357808b
RK
1816 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 3)))
1817 (set (match_dup 0) (xor:SI (match_dup 0) (match_dup 4)))]
1818"
1fd4e8c1 1819{
f357808b
RK
1820 operands[3] = gen_rtx (CONST_INT, VOIDmode,
1821 INTVAL (operands[2]) & 0xffff0000);
1822 operands[4] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0xffff);
1fd4e8c1
RK
1823}")
1824
1825(define_insn ""
cd2b37d9
RK
1826 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1827 (not:SI (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
1828 (match_operand:SI 2 "gpc_reg_operand" "r"))))]
1fd4e8c1
RK
1829 ""
1830 "eqv %0,%1,%2")
1831
1832(define_insn ""
1833 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
cd2b37d9
RK
1834 (compare:CC (not:SI (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
1835 (match_operand:SI 2 "gpc_reg_operand" "r")))
1fd4e8c1
RK
1836 (const_int 0)))
1837 (clobber (match_scratch:SI 3 "=r"))]
1838 ""
1839 "eqv. %3,%1,%2"
1840 [(set_attr "type" "compare")])
1841
1842(define_insn ""
1843 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
cd2b37d9
RK
1844 (compare:CC (not:SI (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
1845 (match_operand:SI 2 "gpc_reg_operand" "r")))
1fd4e8c1 1846 (const_int 0)))
cd2b37d9 1847 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
1848 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
1849 ""
1850 "eqv. %0,%1,%2"
1851 [(set_attr "type" "compare")])
1852
1853(define_insn ""
cd2b37d9
RK
1854 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1855 (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1856 (match_operand:SI 2 "gpc_reg_operand" "r")))]
1fd4e8c1
RK
1857 ""
1858 "andc %0,%2,%1")
1859
1860(define_insn ""
1861 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
cd2b37d9
RK
1862 (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1863 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1
RK
1864 (const_int 0)))
1865 (clobber (match_scratch:SI 3 "=r"))]
1866 ""
1867 "andc. %3,%2,%1"
1868 [(set_attr "type" "compare")])
1869
1870(define_insn ""
1871 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
cd2b37d9
RK
1872 (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1873 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 1874 (const_int 0)))
cd2b37d9 1875 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
1876 (and:SI (not:SI (match_dup 1)) (match_dup 2)))]
1877 ""
1878 "andc. %0,%2,%1"
1879 [(set_attr "type" "compare")])
1880
1881(define_insn ""
cd2b37d9
RK
1882 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1883 (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1884 (match_operand:SI 2 "gpc_reg_operand" "r")))]
1fd4e8c1
RK
1885 ""
1886 "orc %0,%2,%1")
1887
1888(define_insn ""
1889 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
cd2b37d9
RK
1890 (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1891 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1
RK
1892 (const_int 0)))
1893 (clobber (match_scratch:SI 3 "=r"))]
1894 ""
1895 "orc. %3,%2,%1"
1896 [(set_attr "type" "compare")])
1897
1898(define_insn ""
1899 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
cd2b37d9
RK
1900 (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1901 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 1902 (const_int 0)))
cd2b37d9 1903 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
1904 (ior:SI (not:SI (match_dup 1)) (match_dup 2)))]
1905 ""
1906 "orc. %0,%2,%1"
1907 [(set_attr "type" "compare")])
1908
1909(define_insn ""
cd2b37d9 1910 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
deb9225a 1911 (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
cd2b37d9 1912 (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
1fd4e8c1
RK
1913 ""
1914 "nand %0,%1,%2")
1915
1916(define_insn ""
1917 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
deb9225a 1918 (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
cd2b37d9 1919 (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")))
1fd4e8c1
RK
1920 (const_int 0)))
1921 (clobber (match_scratch:SI 3 "=r"))]
1922 ""
1923 "nand. %3,%1,%2"
1924 [(set_attr "type" "compare")])
1925
1926(define_insn ""
1927 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
deb9225a 1928 (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
cd2b37d9 1929 (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")))
1fd4e8c1 1930 (const_int 0)))
cd2b37d9 1931 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
1932 (ior:SI (not:SI (match_dup 1)) (not:SI (match_dup 2))))]
1933 ""
1934 "nand. %0,%1,%2"
1935 [(set_attr "type" "compare")])
1936
1937(define_insn ""
cd2b37d9 1938 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
deb9225a 1939 (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
cd2b37d9 1940 (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
1fd4e8c1
RK
1941 ""
1942 "nor %0,%1,%2")
1943
1944(define_insn ""
1945 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
deb9225a 1946 (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
cd2b37d9 1947 (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")))
1fd4e8c1
RK
1948 (const_int 0)))
1949 (clobber (match_scratch:SI 3 "=r"))]
1950 ""
1951 "nor. %3,%1,%2"
1952 [(set_attr "type" "compare")])
1953
1954(define_insn ""
1955 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
deb9225a 1956 (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
cd2b37d9 1957 (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")))
1fd4e8c1 1958 (const_int 0)))
cd2b37d9 1959 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
1960 (and:SI (not:SI (match_dup 1)) (not:SI (match_dup 2))))]
1961 ""
1962 "nor. %0,%1,%2"
1963 [(set_attr "type" "compare")])
1964
1965;; maskir insn. We need four forms because things might be in arbitrary
1966;; orders. Don't define forms that only set CR fields because these
1967;; would modify an input register.
1968
1969(define_insn ""
cd2b37d9 1970 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
01def764
RK
1971 (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))
1972 (match_operand:SI 1 "gpc_reg_operand" "0"))
1973 (and:SI (match_dup 2)
cd2b37d9 1974 (match_operand:SI 3 "gpc_reg_operand" "r"))))]
ca7f5001 1975 "TARGET_POWER"
01def764 1976 "maskir %0,%3,%2")
1fd4e8c1
RK
1977
1978(define_insn ""
242e8072 1979 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
01def764
RK
1980 (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))
1981 (match_operand:SI 1 "gpc_reg_operand" "0"))
cd2b37d9 1982 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r")
01def764 1983 (match_dup 2))))]
ca7f5001 1984 "TARGET_POWER"
01def764 1985 "maskir %0,%3,%2")
1fd4e8c1
RK
1986
1987(define_insn ""
cd2b37d9 1988 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
01def764 1989 (ior:SI (and:SI (match_operand:SI 2 "gpc_reg_operand" "r")
cd2b37d9 1990 (match_operand:SI 3 "gpc_reg_operand" "r"))
01def764
RK
1991 (and:SI (not:SI (match_dup 2))
1992 (match_operand:SI 1 "gpc_reg_operand" "0"))))]
ca7f5001 1993 "TARGET_POWER"
01def764 1994 "maskir %0,%3,%2")
1fd4e8c1
RK
1995
1996(define_insn ""
cd2b37d9
RK
1997 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1998 (ior:SI (and:SI (match_operand:SI 3 "gpc_reg_operand" "r")
01def764
RK
1999 (match_operand:SI 2 "gpc_reg_operand" "r"))
2000 (and:SI (not:SI (match_dup 2))
2001 (match_operand:SI 1 "gpc_reg_operand" "0"))))]
ca7f5001 2002 "TARGET_POWER"
01def764 2003 "maskir %0,%3,%2")
1fd4e8c1
RK
2004
2005(define_insn ""
2006 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
2007 (compare:CC
01def764
RK
2008 (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))
2009 (match_operand:SI 1 "gpc_reg_operand" "0"))
2010 (and:SI (match_dup 2)
cd2b37d9 2011 (match_operand:SI 3 "gpc_reg_operand" "r")))
1fd4e8c1 2012 (const_int 0)))
cd2b37d9 2013 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
01def764
RK
2014 (ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1))
2015 (and:SI (match_dup 2) (match_dup 3))))]
ca7f5001 2016 "TARGET_POWER"
01def764 2017 "maskir. %0,%3,%2"
1fd4e8c1
RK
2018 [(set_attr "type" "compare")])
2019
2020(define_insn ""
2021 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
2022 (compare:CC
01def764
RK
2023 (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))
2024 (match_operand:SI 1 "gpc_reg_operand" "0"))
cd2b37d9 2025 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r")
01def764 2026 (match_dup 2)))
1fd4e8c1 2027 (const_int 0)))
242e8072 2028 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
01def764
RK
2029 (ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1))
2030 (and:SI (match_dup 3) (match_dup 2))))]
ca7f5001 2031 "TARGET_POWER"
01def764 2032 "maskir. %0,%3,%2"
1fd4e8c1
RK
2033 [(set_attr "type" "compare")])
2034
2035(define_insn ""
2036 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
2037 (compare:CC
01def764 2038 (ior:SI (and:SI (match_operand:SI 2 "gpc_reg_operand" "r")
cd2b37d9 2039 (match_operand:SI 3 "gpc_reg_operand" "r"))
01def764
RK
2040 (and:SI (not:SI (match_dup 2))
2041 (match_operand:SI 1 "gpc_reg_operand" "0")))
1fd4e8c1 2042 (const_int 0)))
cd2b37d9 2043 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
01def764
RK
2044 (ior:SI (and:SI (match_dup 2) (match_dup 3))
2045 (and:SI (not:SI (match_dup 2)) (match_dup 1))))]
ca7f5001 2046 "TARGET_POWER"
01def764 2047 "maskir. %0,%3,%2"
1fd4e8c1
RK
2048 [(set_attr "type" "compare")])
2049
2050(define_insn ""
2051 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
2052 (compare:CC
cd2b37d9 2053 (ior:SI (and:SI (match_operand:SI 3 "gpc_reg_operand" "r")
01def764
RK
2054 (match_operand:SI 2 "gpc_reg_operand" "r"))
2055 (and:SI (not:SI (match_dup 2))
2056 (match_operand:SI 1 "gpc_reg_operand" "0")))
1fd4e8c1 2057 (const_int 0)))
cd2b37d9 2058 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
01def764
RK
2059 (ior:SI (and:SI (match_dup 3) (match_dup 2))
2060 (and:SI (not:SI (match_dup 2)) (match_dup 1))))]
ca7f5001 2061 "TARGET_POWER"
01def764 2062 "maskir. %0,%3,%2"
1fd4e8c1
RK
2063 [(set_attr "type" "compare")])
2064\f
2065;; Rotate and shift insns, in all their variants. These support shifts,
2066;; field inserts and extracts, and various combinations thereof.
034c1be0
MM
2067(define_expand "insv"
2068 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
2069 (match_operand:SI 1 "const_int_operand" "i")
2070 (match_operand:SI 2 "const_int_operand" "i"))
2071 (match_operand:SI 3 "gpc_reg_operand" "r"))]
2072 ""
2073 "
2074{
2075 /* Do not handle 16/8 bit structures that fit in HI/QI modes directly, since
2076 the (SUBREG:SI (REG:HI xxx)) that is otherwise generated can confuse the
2077 compiler if the address of the structure is taken later. */
2078 if (GET_CODE (operands[0]) == SUBREG
2079 && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD))
2080 FAIL;
2081}")
2082
2083(define_insn ""
cd2b37d9 2084 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
1fd4e8c1
RK
2085 (match_operand:SI 1 "const_int_operand" "i")
2086 (match_operand:SI 2 "const_int_operand" "i"))
cd2b37d9 2087 (match_operand:SI 3 "gpc_reg_operand" "r"))]
1fd4e8c1
RK
2088 ""
2089 "*
2090{
2091 int start = INTVAL (operands[2]) & 31;
2092 int size = INTVAL (operands[1]) & 31;
2093
2094 operands[4] = gen_rtx (CONST_INT, VOIDmode, 32 - start - size);
2095 operands[1] = gen_rtx (CONST_INT, VOIDmode, start + size - 1);
a66078ee 2096 return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\";
1fd4e8c1
RK
2097}")
2098
d56d506a
RK
2099(define_insn ""
2100 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
2101 (match_operand:SI 1 "const_int_operand" "i")
2102 (match_operand:SI 2 "const_int_operand" "i"))
2103 (ashift:SI (match_operand:SI 3 "gpc_reg_operand" "r")
2104 (match_operand:SI 4 "const_int_operand" "i")))]
2105 ""
2106 "*
2107{
2108 int shift = INTVAL (operands[4]) & 31;
2109 int start = INTVAL (operands[2]) & 31;
2110 int size = INTVAL (operands[1]) & 31;
2111
a66078ee 2112 operands[4] = gen_rtx (CONST_INT, VOIDmode, shift - start - size);
d56d506a 2113 operands[1] = gen_rtx (CONST_INT, VOIDmode, start + size - 1);
a66078ee 2114 return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\";
d56d506a
RK
2115}")
2116
2117(define_insn ""
2118 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
2119 (match_operand:SI 1 "const_int_operand" "i")
2120 (match_operand:SI 2 "const_int_operand" "i"))
2121 (ashiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r")
2122 (match_operand:SI 4 "const_int_operand" "i")))]
2123 ""
2124 "*
2125{
2126 int shift = INTVAL (operands[4]) & 31;
2127 int start = INTVAL (operands[2]) & 31;
2128 int size = INTVAL (operands[1]) & 31;
2129
a66078ee 2130 operands[4] = gen_rtx (CONST_INT, VOIDmode, 32 - shift - start - size);
d56d506a 2131 operands[1] = gen_rtx (CONST_INT, VOIDmode, start + size - 1);
a66078ee 2132 return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\";
d56d506a
RK
2133}")
2134
2135(define_insn ""
2136 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
2137 (match_operand:SI 1 "const_int_operand" "i")
2138 (match_operand:SI 2 "const_int_operand" "i"))
2139 (lshiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r")
2140 (match_operand:SI 4 "const_int_operand" "i")))]
2141 ""
2142 "*
2143{
2144 int shift = INTVAL (operands[4]) & 31;
2145 int start = INTVAL (operands[2]) & 31;
2146 int size = INTVAL (operands[1]) & 31;
2147
a66078ee 2148 operands[4] = gen_rtx (CONST_INT, VOIDmode, 32 - shift - start - size);
d56d506a 2149 operands[1] = gen_rtx (CONST_INT, VOIDmode, start + size - 1);
a66078ee 2150 return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\";
d56d506a
RK
2151}")
2152
2153(define_insn ""
2154 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
2155 (match_operand:SI 1 "const_int_operand" "i")
2156 (match_operand:SI 2 "const_int_operand" "i"))
2157 (zero_extract:SI (match_operand:SI 3 "gpc_reg_operand" "r")
2158 (match_operand:SI 4 "const_int_operand" "i")
2159 (match_operand:SI 5 "const_int_operand" "i")))]
2160 "INTVAL (operands[4]) >= INTVAL (operands[1])"
2161 "*
2162{
2163 int extract_start = INTVAL (operands[5]) & 31;
2164 int extract_size = INTVAL (operands[4]) & 31;
2165 int insert_start = INTVAL (operands[2]) & 31;
2166 int insert_size = INTVAL (operands[1]) & 31;
2167
2168/* Align extract field with insert field */
2169 operands[5] = gen_rtx (CONST_INT, VOIDmode,
a66078ee 2170 extract_start + extract_size - insert_start - insert_size);
d56d506a 2171 operands[1] = gen_rtx (CONST_INT, VOIDmode, insert_start + insert_size - 1);
a66078ee 2172 return \"{rlimi|rlwimi} %0,%3,%h5,%h2,%h1\";
d56d506a
RK
2173}")
2174
685f3906
DE
2175(define_insn ""
2176 [(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r")
2177 (match_operand:DI 1 "const_int_operand" "i")
2178 (match_operand:DI 2 "const_int_operand" "i"))
2179 (match_operand:DI 3 "gpc_reg_operand" "r"))]
2180 "TARGET_POWERPC64"
2181 "*
2182{
2183 int start = INTVAL (operands[2]) & 63;
2184 int size = INTVAL (operands[1]) & 63;
2185
2186 operands[2] = gen_rtx (CONST_INT, VOIDmode, 64 - start - size);
a66078ee 2187 return \"rldimi %0,%3,%H2,%H1\";
685f3906
DE
2188}")
2189
034c1be0
MM
2190(define_expand "extzv"
2191 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2192 (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2193 (match_operand:SI 2 "const_int_operand" "i")
2194 (match_operand:SI 3 "const_int_operand" "i")))]
2195 ""
2196 "
2197{
2198 /* Do not handle 16/8 bit structures that fit in HI/QI modes directly, since
2199 the (SUBREG:SI (REG:HI xxx)) that is otherwise generated can confuse the
2200 compiler if the address of the structure is taken later. */
2201 if (GET_CODE (operands[0]) == SUBREG
2202 && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD))
2203 FAIL;
2204}")
2205
2206(define_insn ""
cd2b37d9
RK
2207 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2208 (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2209 (match_operand:SI 2 "const_int_operand" "i")
2210 (match_operand:SI 3 "const_int_operand" "i")))]
2211 ""
2212 "*
2213{
2214 int start = INTVAL (operands[3]) & 31;
2215 int size = INTVAL (operands[2]) & 31;
2216
2217 if (start + size >= 32)
2218 operands[3] = const0_rtx;
2219 else
2220 operands[3] = gen_rtx (CONST_INT, VOIDmode, start + size);
ca7f5001 2221 return \"{rlinm|rlwinm} %0,%1,%3,%s2,31\";
1fd4e8c1
RK
2222}")
2223
2224(define_insn ""
2225 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
cd2b37d9 2226 (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2227 (match_operand:SI 2 "const_int_operand" "i")
2228 (match_operand:SI 3 "const_int_operand" "i"))
2229 (const_int 0)))
2230 (clobber (match_scratch:SI 4 "=r"))]
2231 ""
2232 "*
2233{
2234 int start = INTVAL (operands[3]) & 31;
2235 int size = INTVAL (operands[2]) & 31;
2236
a7a975e1
RK
2237 /* If the bitfield being tested fits in the upper or lower half of a
2238 word, it is possible to use andiu. or andil. to test it. This is
2239 useful because the condition register set-use delay is smaller for
2240 andi[ul]. than for rlinm. This doesn't work when the starting bit
2241 position is 0 because the LT and GT bits may be set wrong. */
2242
2243 if ((start > 0 && start + size <= 16) || start >= 16)
df031c43
RK
2244 {
2245 operands[3] = gen_rtx (CONST_INT, VOIDmode,
2246 ((1 << (16 - (start & 15)))
2247 - (1 << (16 - (start & 15) - size))));
2248 if (start < 16)
ca7f5001 2249 return \"{andiu.|andis.} %4,%1,%3\";
df031c43 2250 else
ca7f5001 2251 return \"{andil.|andi.} %4,%1,%3\";
df031c43 2252 }
7e69e155 2253
1fd4e8c1
RK
2254 if (start + size >= 32)
2255 operands[3] = const0_rtx;
2256 else
2257 operands[3] = gen_rtx (CONST_INT, VOIDmode, start + size);
ca7f5001 2258 return \"{rlinm.|rlwinm.} %4,%1,%3,%s2,31\";
1fd4e8c1
RK
2259}"
2260 [(set_attr "type" "compare")])
2261
2262(define_insn ""
2263 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
cd2b37d9 2264 (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2265 (match_operand:SI 2 "const_int_operand" "i")
2266 (match_operand:SI 3 "const_int_operand" "i"))
2267 (const_int 0)))
cd2b37d9 2268 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2269 (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
2270 ""
2271 "*
2272{
2273 int start = INTVAL (operands[3]) & 31;
2274 int size = INTVAL (operands[2]) & 31;
2275
a7a975e1 2276 if (start >= 16 && start + size == 32)
df031c43 2277 {
a7a975e1 2278 operands[3] = gen_rtx (CONST_INT, VOIDmode, (1 << (32 - start)) - 1);
ca7f5001 2279 return \"{andil.|andi.} %0,%1,%3\";
df031c43 2280 }
7e69e155 2281
1fd4e8c1
RK
2282 if (start + size >= 32)
2283 operands[3] = const0_rtx;
2284 else
2285 operands[3] = gen_rtx (CONST_INT, VOIDmode, start + size);
ca7f5001 2286 return \"{rlinm.|rlwinm.} %0,%1,%3,%s2,31\";
1fd4e8c1
RK
2287}"
2288 [(set_attr "type" "delayed_compare")])
2289
685f3906
DE
2290(define_insn ""
2291 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2292 (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2293 (match_operand:DI 2 "const_int_operand" "i")
2294 (match_operand:DI 3 "const_int_operand" "i")))]
2295 "TARGET_POWERPC64"
2296 "*
2297{
2298 int start = INTVAL (operands[3]) & 63;
2299 int size = INTVAL (operands[2]) & 63;
2300
2301 if (start + size >= 64)
2302 operands[3] = const0_rtx;
2303 else
2304 operands[3] = gen_rtx (CONST_INT, VOIDmode, start + size);
2305 operands[2] = gen_rtx (CONST_INT, VOIDmode, 64 - size);
2306 return \"rldicl %0,%1,%3,%2\";
2307}")
2308
2309(define_insn ""
2310 [(set (match_operand:CC 0 "gpc_reg_operand" "=x")
2311 (compare:CC (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2312 (match_operand:DI 2 "const_int_operand" "i")
2313 (match_operand:DI 3 "const_int_operand" "i"))
2314 (const_int 0)))
2315 (clobber (match_scratch:DI 4 "=r"))]
2316 "TARGET_POWERPC64"
2317 "*
2318{
2319 int start = INTVAL (operands[3]) & 63;
2320 int size = INTVAL (operands[2]) & 63;
2321
2322 if (start + size >= 64)
2323 operands[3] = const0_rtx;
2324 else
2325 operands[3] = gen_rtx (CONST_INT, VOIDmode, start + size);
2326 operands[2] = gen_rtx (CONST_INT, VOIDmode, 64 - size);
2327 return \"rldicl. %4,%1,%3,%2\";
2328}")
2329
2330(define_insn ""
2331 [(set (match_operand:CC 4 "gpc_reg_operand" "=x")
2332 (compare:CC (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2333 (match_operand:DI 2 "const_int_operand" "i")
2334 (match_operand:DI 3 "const_int_operand" "i"))
2335 (const_int 0)))
2336 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
2337 (zero_extract:DI (match_dup 1) (match_dup 2) (match_dup 3)))]
2338 "TARGET_POWERPC64"
2339 "*
2340{
2341 int start = INTVAL (operands[3]) & 63;
2342 int size = INTVAL (operands[2]) & 63;
2343
2344 if (start + size >= 64)
2345 operands[3] = const0_rtx;
2346 else
2347 operands[3] = gen_rtx (CONST_INT, VOIDmode, start + size);
2348 operands[2] = gen_rtx (CONST_INT, VOIDmode, 64 - size);
2349 return \"rldicl. %0,%1,%3,%2\";
2350}")
2351
1fd4e8c1 2352(define_insn "rotlsi3"
cd2b37d9
RK
2353 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2354 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2355 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
2356 ""
ca7f5001 2357 "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xffffffff")
1fd4e8c1
RK
2358
2359(define_insn ""
2360 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
cd2b37d9 2361 (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2362 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2363 (const_int 0)))
2364 (clobber (match_scratch:SI 3 "=r"))]
2365 ""
ca7f5001 2366 "{rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffffffff"
1fd4e8c1
RK
2367 [(set_attr "type" "delayed_compare")])
2368
2369(define_insn ""
2370 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
cd2b37d9 2371 (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2372 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2373 (const_int 0)))
cd2b37d9 2374 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2375 (rotate:SI (match_dup 1) (match_dup 2)))]
2376 ""
ca7f5001 2377 "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffffffff"
1fd4e8c1
RK
2378 [(set_attr "type" "delayed_compare")])
2379
2380(define_insn ""
cd2b37d9
RK
2381 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2382 (and:SI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2383 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2384 (match_operand:SI 3 "mask_operand" "L")))]
2385 ""
ca7f5001 2386 "{rl%I2nm|rlw%I2nm} %0,%1,%h2,%m3,%M3")
1fd4e8c1
RK
2387
2388(define_insn ""
2389 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2390 (compare:CC (and:SI
cd2b37d9 2391 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2392 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2393 (match_operand:SI 3 "mask_operand" "L"))
2394 (const_int 0)))
2395 (clobber (match_scratch:SI 4 "=r"))]
2396 ""
ca7f5001 2397 "{rl%I2nm.|rlw%I2nm.} %4,%1,%h2,%m3,%M3"
1fd4e8c1
RK
2398 [(set_attr "type" "delayed_compare")])
2399
2400(define_insn ""
2401 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
2402 (compare:CC (and:SI
cd2b37d9 2403 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2404 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2405 (match_operand:SI 3 "mask_operand" "L"))
2406 (const_int 0)))
cd2b37d9 2407 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2408 (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2409 ""
ca7f5001 2410 "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,%m3,%M3"
1fd4e8c1
RK
2411 [(set_attr "type" "delayed_compare")])
2412
2413(define_insn ""
cd2b37d9 2414 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2415 (zero_extend:SI
2416 (subreg:QI
cd2b37d9 2417 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2418 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0)))]
2419 ""
ca7f5001 2420 "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xff")
1fd4e8c1
RK
2421
2422(define_insn ""
2423 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2424 (compare:CC (zero_extend:SI
2425 (subreg:QI
cd2b37d9 2426 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2427 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0))
2428 (const_int 0)))
2429 (clobber (match_scratch:SI 3 "=r"))]
2430 ""
ca7f5001 2431 "{rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xff"
1fd4e8c1
RK
2432 [(set_attr "type" "delayed_compare")])
2433
2434(define_insn ""
2435 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2436 (compare:CC (zero_extend:SI
2437 (subreg:QI
cd2b37d9 2438 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2439 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0))
2440 (const_int 0)))
cd2b37d9 2441 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2442 (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
2443 ""
ca7f5001 2444 "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xff"
1fd4e8c1
RK
2445 [(set_attr "type" "delayed_compare")])
2446
2447(define_insn ""
cd2b37d9 2448 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2449 (zero_extend:SI
2450 (subreg:HI
cd2b37d9 2451 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2452 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0)))]
2453 ""
ca7f5001 2454 "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xffff")
1fd4e8c1
RK
2455
2456(define_insn ""
2457 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2458 (compare:CC (zero_extend:SI
2459 (subreg:HI
cd2b37d9 2460 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2461 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0))
2462 (const_int 0)))
2463 (clobber (match_scratch:SI 3 "=r"))]
2464 ""
ca7f5001 2465 "{rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffff"
1fd4e8c1
RK
2466 [(set_attr "type" "delayed_compare")])
2467
2468(define_insn ""
2469 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2470 (compare:CC (zero_extend:SI
2471 (subreg:HI
cd2b37d9 2472 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2473 (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0))
2474 (const_int 0)))
cd2b37d9 2475 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2476 (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
2477 ""
ca7f5001 2478 "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffff"
1fd4e8c1
RK
2479 [(set_attr "type" "delayed_compare")])
2480
2481;; Note that we use "sle." instead of "sl." so that we can set
2482;; SHIFT_COUNT_TRUNCATED.
2483
ca7f5001
RK
2484(define_expand "ashlsi3"
2485 [(use (match_operand:SI 0 "gpc_reg_operand" ""))
2486 (use (match_operand:SI 1 "gpc_reg_operand" ""))
2487 (use (match_operand:SI 2 "reg_or_cint_operand" ""))]
2488 ""
2489 "
2490{
2491 if (TARGET_POWER)
2492 emit_insn (gen_ashlsi3_power (operands[0], operands[1], operands[2]));
2493 else
25c341fa 2494 emit_insn (gen_ashlsi3_no_power (operands[0], operands[1], operands[2]));
ca7f5001
RK
2495 DONE;
2496}")
2497
2498(define_insn "ashlsi3_power"
cd2b37d9
RK
2499 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
2500 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
2501 (match_operand:SI 2 "reg_or_cint_operand" "r,i")))
2502 (clobber (match_scratch:SI 3 "=q,X"))]
ca7f5001 2503 "TARGET_POWER"
1fd4e8c1
RK
2504 "@
2505 sle %0,%1,%2
ca7f5001
RK
2506 {sli|slwi} %0,%1,%h2"
2507 [(set_attr "length" "8")])
2508
25c341fa 2509(define_insn "ashlsi3_no_power"
ca7f5001
RK
2510 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2511 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2512 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
25c341fa 2513 "! TARGET_POWER"
d904e9ed 2514 "{sl|slw}%I2 %0,%1,%h2"
b19003d8 2515 [(set_attr "length" "8")])
1fd4e8c1
RK
2516
2517(define_insn ""
2518 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
cd2b37d9 2519 (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
2520 (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
2521 (const_int 0)))
2522 (clobber (match_scratch:SI 3 "=r,r"))
2523 (clobber (match_scratch:SI 4 "=q,X"))]
ca7f5001 2524 "TARGET_POWER"
1fd4e8c1
RK
2525 "@
2526 sle. %3,%1,%2
ca7f5001
RK
2527 {sli.|slwi.} %3,%1,%h2"
2528 [(set_attr "type" "delayed_compare")])
25c341fa 2529
ca7f5001
RK
2530(define_insn ""
2531 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2532 (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2533 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2534 (const_int 0)))
2535 (clobber (match_scratch:SI 3 "=r"))]
8ffd9c51 2536 "! TARGET_POWER"
d904e9ed 2537 "{sl|slw}%I2. %3,%1,%h2"
1fd4e8c1
RK
2538 [(set_attr "type" "delayed_compare")])
2539
2540(define_insn ""
2541 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
cd2b37d9 2542 (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
2543 (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
2544 (const_int 0)))
cd2b37d9 2545 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
2546 (ashift:SI (match_dup 1) (match_dup 2)))
2547 (clobber (match_scratch:SI 4 "=q,X"))]
ca7f5001 2548 "TARGET_POWER"
1fd4e8c1
RK
2549 "@
2550 sle. %0,%1,%2
ca7f5001
RK
2551 {sli.|slwi.} %0,%1,%h2"
2552 [(set_attr "type" "delayed_compare")])
25c341fa 2553
ca7f5001
RK
2554(define_insn ""
2555 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2556 (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2557 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2558 (const_int 0)))
2559 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
2560 (ashift:SI (match_dup 1) (match_dup 2)))]
8ffd9c51 2561 "! TARGET_POWER"
d904e9ed 2562 "{sl|slw}%I2. %0,%1,%h2"
1fd4e8c1
RK
2563 [(set_attr "type" "delayed_compare")])
2564
2565(define_insn ""
cd2b37d9
RK
2566 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2567 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2568 (match_operand:SI 2 "const_int_operand" "i"))
2569 (match_operand:SI 3 "mask_operand" "L")))]
2570 "includes_lshift_p (operands[2], operands[3])"
d56d506a 2571 "{rlinm|rlwinm} %0,%1,%h2,%m3,%M3")
1fd4e8c1
RK
2572
2573(define_insn ""
2574 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2575 (compare:CC
cd2b37d9 2576 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2577 (match_operand:SI 2 "const_int_operand" "i"))
2578 (match_operand:SI 3 "mask_operand" "L"))
2579 (const_int 0)))
2580 (clobber (match_scratch:SI 4 "=r"))]
2581 "includes_lshift_p (operands[2], operands[3])"
d56d506a 2582 "{rlinm.|rlwinm.} %4,%1,%h2,%m3,%M3"
1fd4e8c1
RK
2583 [(set_attr "type" "delayed_compare")])
2584
2585(define_insn ""
2586 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
2587 (compare:CC
cd2b37d9 2588 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2589 (match_operand:SI 2 "const_int_operand" "i"))
2590 (match_operand:SI 3 "mask_operand" "L"))
2591 (const_int 0)))
cd2b37d9 2592 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2593 (and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2594 "includes_lshift_p (operands[2], operands[3])"
d56d506a 2595 "{rlinm.|rlwinm.} %0,%1,%h2,%m3,%M3"
1fd4e8c1
RK
2596 [(set_attr "type" "delayed_compare")])
2597
ca7f5001 2598;; The AIX assembler mis-handles "sri x,x,0", so write that case as
5c23c401 2599;; "sli x,x,0".
ca7f5001
RK
2600(define_expand "lshrsi3"
2601 [(use (match_operand:SI 0 "gpc_reg_operand" ""))
2602 (use (match_operand:SI 1 "gpc_reg_operand" ""))
2603 (use (match_operand:SI 2 "reg_or_cint_operand" ""))]
2604 ""
2605 "
2606{
2607 if (TARGET_POWER)
2608 emit_insn (gen_lshrsi3_power (operands[0], operands[1], operands[2]));
2609 else
25c341fa 2610 emit_insn (gen_lshrsi3_no_power (operands[0], operands[1], operands[2]));
ca7f5001
RK
2611 DONE;
2612}")
2613
2614(define_insn "lshrsi3_power"
bdf423cb
MM
2615 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
2616 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r")
2617 (match_operand:SI 2 "reg_or_cint_operand" "r,O,i")))
2618 (clobber (match_scratch:SI 3 "=q,X,X"))]
ca7f5001 2619 "TARGET_POWER"
1fd4e8c1
RK
2620 "@
2621 sre %0,%1,%2
bdf423cb 2622 mr %0,%1
ca7f5001
RK
2623 {s%A2i|s%A2wi} %0,%1,%h2")
2624
25c341fa 2625(define_insn "lshrsi3_no_power"
bdf423cb
MM
2626 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
2627 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
2628 (match_operand:SI 2 "reg_or_cint_operand" "O,ri")))]
25c341fa 2629 "! TARGET_POWER"
bdf423cb
MM
2630 "@
2631 mr %0,%1
2632 {sr|srw}%I2 %0,%1,%h2")
1fd4e8c1
RK
2633
2634(define_insn ""
bdf423cb
MM
2635 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x")
2636 (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r")
2637 (match_operand:SI 2 "reg_or_cint_operand" "r,O,i"))
1fd4e8c1 2638 (const_int 0)))
bdf423cb
MM
2639 (clobber (match_scratch:SI 3 "=r,X,r"))
2640 (clobber (match_scratch:SI 4 "=q,X,X"))]
ca7f5001 2641 "TARGET_POWER"
1fd4e8c1
RK
2642 "@
2643 sre. %3,%1,%2
bdf423cb 2644 mr. %1,%1
ca7f5001
RK
2645 {s%A2i.|s%A2wi.} %3,%1,%h2"
2646 [(set_attr "type" "delayed_compare")])
2647
2648(define_insn ""
bdf423cb
MM
2649 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
2650 (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
2651 (match_operand:SI 2 "reg_or_cint_operand" "O,ri"))
ca7f5001 2652 (const_int 0)))
bdf423cb 2653 (clobber (match_scratch:SI 3 "=X,r"))]
25c341fa 2654 "! TARGET_POWER"
bdf423cb
MM
2655 "@
2656 mr. %1,%1
2657 {sr|srw}%I2. %3,%1,%h2"
1fd4e8c1
RK
2658 [(set_attr "type" "delayed_compare")])
2659
2660(define_insn ""
bdf423cb
MM
2661 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x")
2662 (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r")
2663 (match_operand:SI 2 "reg_or_cint_operand" "r,O,i"))
1fd4e8c1 2664 (const_int 0)))
bdf423cb 2665 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
1fd4e8c1 2666 (lshiftrt:SI (match_dup 1) (match_dup 2)))
bdf423cb 2667 (clobber (match_scratch:SI 4 "=q,X,X"))]
ca7f5001 2668 "TARGET_POWER"
1fd4e8c1
RK
2669 "@
2670 sre. %0,%1,%2
bdf423cb 2671 mr. %0,%1
ca7f5001
RK
2672 {s%A2i.|s%A2wi.} %0,%1,%h2"
2673 [(set_attr "type" "delayed_compare")])
2674
2675(define_insn ""
bdf423cb
MM
2676 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
2677 (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
2678 (match_operand:SI 2 "reg_or_cint_operand" "O,ri"))
ca7f5001 2679 (const_int 0)))
bdf423cb 2680 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
ca7f5001 2681 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
25c341fa 2682 "! TARGET_POWER"
bdf423cb
MM
2683 "@
2684 mr. %0,%1
2685 {sr|srw}%I2. %0,%1,%h2"
1fd4e8c1
RK
2686 [(set_attr "type" "delayed_compare")])
2687
2688(define_insn ""
cd2b37d9
RK
2689 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2690 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2691 (match_operand:SI 2 "const_int_operand" "i"))
2692 (match_operand:SI 3 "mask_operand" "L")))]
2693 "includes_rshift_p (operands[2], operands[3])"
ca7f5001 2694 "{rlinm|rlwinm} %0,%1,%s2,%m3,%M3")
1fd4e8c1
RK
2695
2696(define_insn ""
2697 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2698 (compare:CC
cd2b37d9 2699 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2700 (match_operand:SI 2 "const_int_operand" "i"))
2701 (match_operand:SI 3 "mask_operand" "L"))
2702 (const_int 0)))
2703 (clobber (match_scratch:SI 4 "=r"))]
2704 "includes_rshift_p (operands[2], operands[3])"
ca7f5001 2705 "{rlinm.|rlwinm.} %4,%1,%s2,%m3,%M3"
1fd4e8c1
RK
2706 [(set_attr "type" "delayed_compare")])
2707
2708(define_insn ""
2709 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
2710 (compare:CC
cd2b37d9 2711 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2712 (match_operand:SI 2 "const_int_operand" "i"))
2713 (match_operand:SI 3 "mask_operand" "L"))
2714 (const_int 0)))
cd2b37d9 2715 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2716 (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2717 "includes_rshift_p (operands[2], operands[3])"
ca7f5001 2718 "{rlinm.|rlwinm.} %0,%1,%s2,%m3,%M3"
1fd4e8c1
RK
2719 [(set_attr "type" "delayed_compare")])
2720
2721(define_insn ""
cd2b37d9 2722 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2723 (zero_extend:SI
2724 (subreg:QI
cd2b37d9 2725 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2726 (match_operand:SI 2 "const_int_operand" "i")) 0)))]
2727 "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 255))"
ca7f5001 2728 "{rlinm|rlwinm} %0,%1,%s2,0xff")
1fd4e8c1
RK
2729
2730(define_insn ""
2731 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2732 (compare:CC
2733 (zero_extend:SI
2734 (subreg:QI
cd2b37d9 2735 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2736 (match_operand:SI 2 "const_int_operand" "i")) 0))
2737 (const_int 0)))
2738 (clobber (match_scratch:SI 3 "=r"))]
2739 "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 255))"
ca7f5001 2740 "{rlinm.|rlwinm.} %3,%1,%s2,0xff"
1fd4e8c1
RK
2741 [(set_attr "type" "delayed_compare")])
2742
2743(define_insn ""
2744 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2745 (compare:CC
2746 (zero_extend:SI
2747 (subreg:QI
cd2b37d9 2748 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2749 (match_operand:SI 2 "const_int_operand" "i")) 0))
2750 (const_int 0)))
cd2b37d9 2751 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2752 (zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
2753 "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 255))"
ca7f5001 2754 "{rlinm.|rlwinm.} %0,%1,%s2,0xff"
1fd4e8c1
RK
2755 [(set_attr "type" "delayed_compare")])
2756
2757(define_insn ""
cd2b37d9 2758 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2759 (zero_extend:SI
2760 (subreg:HI
cd2b37d9 2761 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2762 (match_operand:SI 2 "const_int_operand" "i")) 0)))]
2763 "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 65535))"
ca7f5001 2764 "{rlinm|rlwinm} %0,%1,%s2,0xffff")
1fd4e8c1
RK
2765
2766(define_insn ""
2767 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2768 (compare:CC
2769 (zero_extend:SI
2770 (subreg:HI
cd2b37d9 2771 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2772 (match_operand:SI 2 "const_int_operand" "i")) 0))
2773 (const_int 0)))
2774 (clobber (match_scratch:SI 3 "=r"))]
2775 "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 65535))"
ca7f5001 2776 "{rlinm.|rlwinm.} %3,%1,%s2,0xffff"
1fd4e8c1
RK
2777 [(set_attr "type" "delayed_compare")])
2778
2779(define_insn ""
2780 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2781 (compare:CC
2782 (zero_extend:SI
2783 (subreg:HI
cd2b37d9 2784 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
2785 (match_operand:SI 2 "const_int_operand" "i")) 0))
2786 (const_int 0)))
cd2b37d9 2787 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
2788 (zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
2789 "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 65535))"
ca7f5001 2790 "{rlinm.|rlwinm.} %0,%1,%s2,0xffff"
1fd4e8c1
RK
2791 [(set_attr "type" "delayed_compare")])
2792
2793(define_insn ""
cd2b37d9 2794 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
1fd4e8c1 2795 (const_int 1)
cd2b37d9
RK
2796 (match_operand:SI 1 "gpc_reg_operand" "r"))
2797 (ashiftrt:SI (match_operand:SI 2 "gpc_reg_operand" "r")
1fd4e8c1 2798 (const_int 31)))]
ca7f5001 2799 "TARGET_POWER"
1fd4e8c1
RK
2800 "rrib %0,%1,%2")
2801
2802(define_insn ""
cd2b37d9 2803 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
1fd4e8c1 2804 (const_int 1)
cd2b37d9
RK
2805 (match_operand:SI 1 "gpc_reg_operand" "r"))
2806 (lshiftrt:SI (match_operand:SI 2 "gpc_reg_operand" "r")
1fd4e8c1 2807 (const_int 31)))]
ca7f5001 2808 "TARGET_POWER"
1fd4e8c1
RK
2809 "rrib %0,%1,%2")
2810
2811(define_insn ""
cd2b37d9 2812 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
1fd4e8c1 2813 (const_int 1)
cd2b37d9
RK
2814 (match_operand:SI 1 "gpc_reg_operand" "r"))
2815 (zero_extract:SI (match_operand:SI 2 "gpc_reg_operand" "r")
1fd4e8c1
RK
2816 (const_int 1)
2817 (const_int 0)))]
ca7f5001 2818 "TARGET_POWER"
1fd4e8c1
RK
2819 "rrib %0,%1,%2")
2820
ca7f5001
RK
2821(define_expand "ashrsi3"
2822 [(set (match_operand:SI 0 "gpc_reg_operand" "")
2823 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
2824 (match_operand:SI 2 "reg_or_cint_operand" "")))]
2825 ""
2826 "
2827{
2828 if (TARGET_POWER)
2829 emit_insn (gen_ashrsi3_power (operands[0], operands[1], operands[2]));
2830 else
25c341fa 2831 emit_insn (gen_ashrsi3_no_power (operands[0], operands[1], operands[2]));
ca7f5001
RK
2832 DONE;
2833}")
2834
2835(define_insn "ashrsi3_power"
cd2b37d9
RK
2836 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
2837 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
2838 (match_operand:SI 2 "reg_or_cint_operand" "r,i")))
2839 (clobber (match_scratch:SI 3 "=q,X"))]
ca7f5001 2840 "TARGET_POWER"
1fd4e8c1
RK
2841 "@
2842 srea %0,%1,%2
ca7f5001
RK
2843 {srai|srawi} %0,%1,%h2")
2844
25c341fa 2845(define_insn "ashrsi3_no_power"
ca7f5001
RK
2846 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2847 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2848 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
25c341fa 2849 "! TARGET_POWER"
d904e9ed 2850 "{sra|sraw}%I2 %0,%1,%h2")
1fd4e8c1
RK
2851
2852(define_insn ""
2853 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
cd2b37d9 2854 (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
2855 (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
2856 (const_int 0)))
2857 (clobber (match_scratch:SI 3 "=r,r"))
2858 (clobber (match_scratch:SI 4 "=q,X"))]
ca7f5001 2859 "TARGET_POWER"
1fd4e8c1
RK
2860 "@
2861 srea. %3,%1,%2
ca7f5001
RK
2862 {srai.|srawi.} %3,%1,%h2"
2863 [(set_attr "type" "delayed_compare")])
2864
2865(define_insn ""
2866 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
2867 (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2868 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2869 (const_int 0)))
2870 (clobber (match_scratch:SI 3 "=r"))]
25c341fa 2871 "! TARGET_POWER"
d904e9ed 2872 "{sra|sraw}%I2. %3,%1,%h2"
1fd4e8c1
RK
2873 [(set_attr "type" "delayed_compare")])
2874
2875(define_insn ""
2876 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
cd2b37d9 2877 (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
2878 (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
2879 (const_int 0)))
cd2b37d9 2880 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
2881 (ashiftrt:SI (match_dup 1) (match_dup 2)))
2882 (clobber (match_scratch:SI 4 "=q,X"))]
ca7f5001 2883 "TARGET_POWER"
1fd4e8c1
RK
2884 "@
2885 srea. %0,%1,%2
7f340546 2886 {srai.|srawi.} %0,%1,%h2"
1fd4e8c1
RK
2887 [(set_attr "type" "delayed_compare")])
2888
ca7f5001
RK
2889(define_insn ""
2890 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
2891 (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2892 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
2893 (const_int 0)))
2894 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
2895 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
25c341fa 2896 "! TARGET_POWER"
d904e9ed 2897 "{sra|sraw}%I2. %0,%1,%h2"
ca7f5001 2898 [(set_attr "type" "delayed_compare")])
1fd4e8c1
RK
2899\f
2900;; Floating-point insns, excluding normal data motion.
2901;;
ca7f5001
RK
2902;; PowerPC has a full set of single-precision floating point instructions.
2903;;
2904;; For the POWER architecture, we pretend that we have both SFmode and
2905;; DFmode insns, while, in fact, all fp insns are actually done in double.
2906;; The only conversions we will do will be when storing to memory. In that
2907;; case, we will use the "frsp" instruction before storing.
1fd4e8c1
RK
2908;;
2909;; Note that when we store into a single-precision memory location, we need to
2910;; use the frsp insn first. If the register being stored isn't dead, we
2911;; need a scratch register for the frsp. But this is difficult when the store
2912;; is done by reload. It is not incorrect to do the frsp on the register in
2913;; this case, we just lose precision that we would have otherwise gotten but
2914;; is not guaranteed. Perhaps this should be tightened up at some point.
2915
e8112008 2916(define_insn "extendsfdf2"
cd2b37d9 2917 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
e8112008 2918 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f")))]
d14a6d05 2919 "TARGET_HARD_FLOAT"
e8112008 2920 "*
5c30aff8 2921{
e8112008
RK
2922 if (REGNO (operands[0]) == REGNO (operands[1]))
2923 return \"\";
2924 else
2925 return \"fmr %0,%1\";
2926}"
2927 [(set_attr "type" "fp")])
1fd4e8c1
RK
2928
2929(define_insn "truncdfsf2"
cd2b37d9
RK
2930 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2931 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "f")))]
d14a6d05 2932 "TARGET_HARD_FLOAT"
dcac138d 2933 "frsp %0,%1"
1fd4e8c1
RK
2934 [(set_attr "type" "fp")])
2935
455350f4
RK
2936(define_insn "aux_truncdfsf2"
2937 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2938 (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] 0))]
2939 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
2940 "frsp %0,%1"
2941 [(set_attr "type" "fp")])
2942
1fd4e8c1 2943(define_insn "negsf2"
cd2b37d9
RK
2944 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2945 (neg:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
d14a6d05 2946 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
2947 "fneg %0,%1"
2948 [(set_attr "type" "fp")])
2949
2950(define_insn "abssf2"
cd2b37d9
RK
2951 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2952 (abs:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
d14a6d05 2953 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
2954 "fabs %0,%1"
2955 [(set_attr "type" "fp")])
2956
2957(define_insn ""
cd2b37d9
RK
2958 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2959 (neg:SF (abs:SF (match_operand:SF 1 "gpc_reg_operand" "f"))))]
d14a6d05 2960 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
2961 "fnabs %0,%1"
2962 [(set_attr "type" "fp")])
2963
ca7f5001
RK
2964(define_expand "addsf3"
2965 [(set (match_operand:SF 0 "gpc_reg_operand" "")
2966 (plus:SF (match_operand:SF 1 "gpc_reg_operand" "")
2967 (match_operand:SF 2 "gpc_reg_operand" "")))]
d14a6d05 2968 "TARGET_HARD_FLOAT"
ca7f5001
RK
2969 "")
2970
2971(define_insn ""
cd2b37d9
RK
2972 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2973 (plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2974 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 2975 "TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 2976 "fadds %0,%1,%2"
ca7f5001
RK
2977 [(set_attr "type" "fp")])
2978
2979(define_insn ""
2980 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2981 (plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
2982 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 2983 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 2984 "{fa|fadd} %0,%1,%2"
ca7f5001
RK
2985 [(set_attr "type" "fp")])
2986
2987(define_expand "subsf3"
2988 [(set (match_operand:SF 0 "gpc_reg_operand" "")
2989 (minus:SF (match_operand:SF 1 "gpc_reg_operand" "")
2990 (match_operand:SF 2 "gpc_reg_operand" "")))]
d14a6d05 2991 "TARGET_HARD_FLOAT"
ca7f5001
RK
2992 "")
2993
2994(define_insn ""
2995 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
2996 (minus:SF (match_operand:SF 1 "gpc_reg_operand" "f")
2997 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 2998 "TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 2999 "fsubs %0,%1,%2"
1fd4e8c1
RK
3000 [(set_attr "type" "fp")])
3001
ca7f5001 3002(define_insn ""
cd2b37d9
RK
3003 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3004 (minus:SF (match_operand:SF 1 "gpc_reg_operand" "f")
3005 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 3006 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 3007 "{fs|fsub} %0,%1,%2"
ca7f5001
RK
3008 [(set_attr "type" "fp")])
3009
3010(define_expand "mulsf3"
3011 [(set (match_operand:SF 0 "gpc_reg_operand" "")
3012 (mult:SF (match_operand:SF 1 "gpc_reg_operand" "")
3013 (match_operand:SF 2 "gpc_reg_operand" "")))]
d14a6d05 3014 "TARGET_HARD_FLOAT"
ca7f5001
RK
3015 "")
3016
3017(define_insn ""
3018 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3019 (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3020 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 3021 "TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 3022 "fmuls %0,%1,%2"
1fd4e8c1
RK
3023 [(set_attr "type" "fp")])
3024
ca7f5001 3025(define_insn ""
cd2b37d9
RK
3026 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3027 (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3028 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 3029 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 3030 "{fm|fmul} %0,%1,%2"
0780f386 3031 [(set_attr "type" "dmul")])
1fd4e8c1 3032
ca7f5001
RK
3033(define_expand "divsf3"
3034 [(set (match_operand:SF 0 "gpc_reg_operand" "")
3035 (div:SF (match_operand:SF 1 "gpc_reg_operand" "")
3036 (match_operand:SF 2 "gpc_reg_operand" "")))]
d14a6d05 3037 "TARGET_HARD_FLOAT"
ca7f5001
RK
3038 "")
3039
3040(define_insn ""
cd2b37d9
RK
3041 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3042 (div:SF (match_operand:SF 1 "gpc_reg_operand" "f")
3043 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 3044 "TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 3045 "fdivs %0,%1,%2"
ca7f5001
RK
3046 [(set_attr "type" "sdiv")])
3047
3048(define_insn ""
3049 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3050 (div:SF (match_operand:SF 1 "gpc_reg_operand" "f")
3051 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 3052 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 3053 "{fd|fdiv} %0,%1,%2"
0780f386 3054 [(set_attr "type" "ddiv")])
1fd4e8c1
RK
3055
3056(define_insn ""
cd2b37d9
RK
3057 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3058 (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3059 (match_operand:SF 2 "gpc_reg_operand" "f"))
3060 (match_operand:SF 3 "gpc_reg_operand" "f")))]
d14a6d05 3061 "TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 3062 "fmadds %0,%1,%2,%3"
ca7f5001
RK
3063 [(set_attr "type" "fp")])
3064
3065(define_insn ""
3066 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3067 (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3068 (match_operand:SF 2 "gpc_reg_operand" "f"))
3069 (match_operand:SF 3 "gpc_reg_operand" "f")))]
d14a6d05 3070 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 3071 "{fma|fmadd} %0,%1,%2,%3"
cf27b467 3072 [(set_attr "type" "dmul")])
1fd4e8c1
RK
3073
3074(define_insn ""
cd2b37d9
RK
3075 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3076 (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3077 (match_operand:SF 2 "gpc_reg_operand" "f"))
3078 (match_operand:SF 3 "gpc_reg_operand" "f")))]
d14a6d05 3079 "TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 3080 "fmsubs %0,%1,%2,%3"
ca7f5001
RK
3081 [(set_attr "type" "fp")])
3082
3083(define_insn ""
3084 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3085 (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3086 (match_operand:SF 2 "gpc_reg_operand" "f"))
3087 (match_operand:SF 3 "gpc_reg_operand" "f")))]
d14a6d05 3088 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 3089 "{fms|fmsub} %0,%1,%2,%3"
cf27b467 3090 [(set_attr "type" "dmul")])
1fd4e8c1
RK
3091
3092(define_insn ""
cd2b37d9
RK
3093 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3094 (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3095 (match_operand:SF 2 "gpc_reg_operand" "f"))
3096 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
d14a6d05 3097 "TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 3098 "fnmadds %0,%1,%2,%3"
ca7f5001
RK
3099 [(set_attr "type" "fp")])
3100
3101(define_insn ""
3102 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3103 (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3104 (match_operand:SF 2 "gpc_reg_operand" "f"))
3105 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
d14a6d05 3106 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 3107 "{fnma|fnmadd} %0,%1,%2,%3"
cf27b467 3108 [(set_attr "type" "dmul")])
1fd4e8c1
RK
3109
3110(define_insn ""
cd2b37d9
RK
3111 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3112 (neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3113 (match_operand:SF 2 "gpc_reg_operand" "f"))
3114 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
d14a6d05 3115 "TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 3116 "fnmsubs %0,%1,%2,%3"
ca7f5001
RK
3117 [(set_attr "type" "fp")])
3118
3119(define_insn ""
3120 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3121 (neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
3122 (match_operand:SF 2 "gpc_reg_operand" "f"))
3123 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
d14a6d05 3124 "! TARGET_POWERPC && TARGET_HARD_FLOAT"
b26c8351 3125 "{fnms|fnmsub} %0,%1,%2,%3"
cf27b467 3126 [(set_attr "type" "dmul")])
1fd4e8c1 3127
ca7f5001
RK
3128(define_expand "sqrtsf2"
3129 [(set (match_operand:SF 0 "gpc_reg_operand" "")
3130 (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "")))]
d14a6d05 3131 "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT"
ca7f5001
RK
3132 "")
3133
3134(define_insn ""
3135 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3136 (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
d14a6d05 3137 "TARGET_PPC_GPOPT && TARGET_HARD_FLOAT"
ca7f5001
RK
3138 "fsqrts %0,%1"
3139 [(set_attr "type" "ssqrt")])
3140
3141(define_insn ""
3142 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3143 (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
d14a6d05 3144 "TARGET_POWER2 && TARGET_HARD_FLOAT"
ca7f5001
RK
3145 "fsqrt %0,%1"
3146 [(set_attr "type" "dsqrt")])
3147
94d7001a
RK
3148;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
3149;; fsel instruction and some auxiliary computations. Then we just have a
3150;; single DEFINE_INSN for fsel and the define_splits to make them if made by
8e871c05
RK
3151;; combine.
3152(define_expand "maxsf3"
3153 [(set (match_dup 3)
3154 (minus:SF (match_operand:SF 1 "gpc_reg_operand" "")
3155 (match_operand:SF 2 "gpc_reg_operand" "")))
3156 (set (match_operand:SF 0 "gpc_reg_operand" "")
3157 (if_then_else:SF (ge (match_dup 3)
3158 (const_int 0))
3159 (match_dup 1)
3160 (match_dup 2)))]
d14a6d05 3161 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3162 "
3163{ operands[3] = gen_reg_rtx (SFmode); }")
2f607b94 3164
8e871c05
RK
3165(define_split
3166 [(set (match_operand:SF 0 "gpc_reg_operand" "")
3167 (smax:SF (match_operand:SF 1 "gpc_reg_operand" "")
f63184ac 3168 (match_operand:SF 2 "gpc_reg_operand" "")))
8e871c05 3169 (clobber (match_operand:SF 3 "gpc_reg_operand" ""))]
d14a6d05 3170 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3171 [(set (match_dup 3)
3172 (minus:SF (match_dup 1) (match_dup 2)))
a81bd72f 3173 (set (match_dup 0)
8e871c05
RK
3174 (if_then_else:SF (ge (match_dup 3)
3175 (const_int 0))
3176 (match_dup 1)
3177 (match_dup 2)))]
3178 "")
2f607b94 3179
8e871c05
RK
3180(define_expand "minsf3"
3181 [(set (match_dup 3)
3182 (minus:SF (match_operand:SF 2 "gpc_reg_operand" "")
3183 (match_operand:SF 1 "gpc_reg_operand" "")))
3184 (set (match_operand:SF 0 "gpc_reg_operand" "")
3185 (if_then_else:SF (ge (match_dup 3)
3186 (const_int 0))
3187 (match_dup 1)
3188 (match_dup 2)))]
d14a6d05 3189 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3190 "
3191{ operands[3] = gen_reg_rtx (SFmode); }")
2f607b94 3192
8e871c05
RK
3193(define_split
3194 [(set (match_operand:SF 0 "gpc_reg_operand" "")
3195 (smin:SF (match_operand:SF 1 "gpc_reg_operand" "")
f63184ac 3196 (match_operand:SF 2 "gpc_reg_operand" "")))
8e871c05 3197 (clobber (match_operand:SF 3 "gpc_reg_operand" ""))]
d14a6d05 3198 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3199 [(set (match_dup 3)
3200 (minus:SF (match_dup 2) (match_dup 1)))
a81bd72f 3201 (set (match_dup 0)
8e871c05
RK
3202 (if_then_else:SF (ge (match_dup 3)
3203 (const_int 0))
3204 (match_dup 1)
3205 (match_dup 2)))]
3206 "")
2f607b94 3207
94d7001a
RK
3208(define_expand "movsfcc"
3209 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3210 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3211 (match_operand:SF 2 "gpc_reg_operand" "f")
3212 (match_operand:SF 3 "gpc_reg_operand" "f")))]
d14a6d05 3213 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
94d7001a
RK
3214 "
3215{
3216 rtx temp, op0, op1;
3217 enum rtx_code code = GET_CODE (operands[1]);
3218 if (! rs6000_compare_fp_p)
3219 FAIL;
3220 switch (code)
3221 {
3222 case GE: case EQ: case NE:
3223 op0 = rs6000_compare_op0;
3224 op1 = rs6000_compare_op1;
3225 break;
3226 case GT:
3227 op0 = rs6000_compare_op1;
3228 op1 = rs6000_compare_op0;
3229 temp = operands[2]; operands[2] = operands[3]; operands[3] = temp;
3230 break;
3231 case LE:
3232 op0 = rs6000_compare_op1;
3233 op1 = rs6000_compare_op0;
3234 break;
3235 case LT:
3236 op0 = rs6000_compare_op0;
3237 op1 = rs6000_compare_op1;
3238 temp = operands[2]; operands[2] = operands[3]; operands[3] = temp;
3239 break;
3240 default:
3241 FAIL;
3242 }
3243 if (GET_MODE (rs6000_compare_op0) == DFmode)
3244 {
3245 temp = gen_reg_rtx (DFmode);
3246 emit_insn (gen_subdf3 (temp, op0, op1));
3247 emit_insn (gen_fseldfsf4 (operands[0], temp, operands[2], operands[3]));
3248 if (code == EQ)
3249 {
3250 emit_insn (gen_negdf2 (temp, temp));
3251 emit_insn (gen_fseldfsf4 (operands[0], temp, operands[0], operands[3]));
3252 }
3253 if (code == NE)
3254 {
3255 emit_insn (gen_negdf2 (temp, temp));
3256 emit_insn (gen_fseldfsf4 (operands[0], temp, operands[3], operands[0]));
3257 }
3258 }
3259 else
3260 {
3261 temp = gen_reg_rtx (SFmode);
3262 emit_insn (gen_subsf3 (temp, op0, op1));
3263 emit_insn (gen_fselsfsf4 (operands[0], temp, operands[2], operands[3]));
3264 if (code == EQ)
3265 {
3266 emit_insn (gen_negsf2 (temp, temp));
3267 emit_insn (gen_fselsfsf4 (operands[0], temp, operands[0], operands[3]));
3268 }
3269 if (code == NE)
3270 {
3271 emit_insn (gen_negsf2 (temp, temp));
3272 emit_insn (gen_fselsfsf4 (operands[0], temp, operands[3], operands[0]));
3273 }
3274 }
3275 DONE;
3276}")
d56d506a 3277
94d7001a 3278(define_insn "fselsfsf4"
8e871c05
RK
3279 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3280 (if_then_else:SF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
3281 (const_int 0))
3282 (match_operand:SF 2 "gpc_reg_operand" "f")
3283 (match_operand:SF 3 "gpc_reg_operand" "f")))]
d14a6d05 3284 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3285 "fsel %0,%1,%2,%3"
3286 [(set_attr "type" "fp")])
2f607b94 3287
94d7001a
RK
3288(define_insn "fseldfsf4"
3289 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
3290 (if_then_else:SF (ge (match_operand:DF 1 "gpc_reg_operand" "f")
3291 (const_int 0))
3292 (match_operand:SF 2 "gpc_reg_operand" "f")
3293 (match_operand:SF 3 "gpc_reg_operand" "f")))]
d14a6d05 3294 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
94d7001a
RK
3295 "fsel %0,%1,%2,%3"
3296 [(set_attr "type" "fp")])
d56d506a 3297
1fd4e8c1 3298(define_insn "negdf2"
cd2b37d9
RK
3299 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3300 (neg:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
d14a6d05 3301 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
3302 "fneg %0,%1"
3303 [(set_attr "type" "fp")])
3304
3305(define_insn "absdf2"
cd2b37d9
RK
3306 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3307 (abs:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
d14a6d05 3308 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
3309 "fabs %0,%1"
3310 [(set_attr "type" "fp")])
3311
3312(define_insn ""
cd2b37d9
RK
3313 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3314 (neg:DF (abs:DF (match_operand:DF 1 "gpc_reg_operand" "f"))))]
d14a6d05 3315 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
3316 "fnabs %0,%1"
3317 [(set_attr "type" "fp")])
3318
3319(define_insn "adddf3"
cd2b37d9
RK
3320 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3321 (plus:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
3322 (match_operand:DF 2 "gpc_reg_operand" "f")))]
d14a6d05 3323 "TARGET_HARD_FLOAT"
ca7f5001 3324 "{fa|fadd} %0,%1,%2"
1fd4e8c1
RK
3325 [(set_attr "type" "fp")])
3326
3327(define_insn "subdf3"
cd2b37d9
RK
3328 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3329 (minus:DF (match_operand:DF 1 "gpc_reg_operand" "f")
3330 (match_operand:DF 2 "gpc_reg_operand" "f")))]
d14a6d05 3331 "TARGET_HARD_FLOAT"
ca7f5001 3332 "{fs|fsub} %0,%1,%2"
1fd4e8c1
RK
3333 [(set_attr "type" "fp")])
3334
3335(define_insn "muldf3"
cd2b37d9
RK
3336 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3337 (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
3338 (match_operand:DF 2 "gpc_reg_operand" "f")))]
d14a6d05 3339 "TARGET_HARD_FLOAT"
ca7f5001 3340 "{fm|fmul} %0,%1,%2"
cfb557c4 3341 [(set_attr "type" "dmul")])
1fd4e8c1
RK
3342
3343(define_insn "divdf3"
cd2b37d9
RK
3344 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3345 (div:DF (match_operand:DF 1 "gpc_reg_operand" "f")
3346 (match_operand:DF 2 "gpc_reg_operand" "f")))]
d14a6d05 3347 "TARGET_HARD_FLOAT"
ca7f5001 3348 "{fd|fdiv} %0,%1,%2"
cfb557c4 3349 [(set_attr "type" "ddiv")])
1fd4e8c1
RK
3350
3351(define_insn ""
cd2b37d9
RK
3352 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3353 (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
3354 (match_operand:DF 2 "gpc_reg_operand" "f"))
3355 (match_operand:DF 3 "gpc_reg_operand" "f")))]
d14a6d05 3356 "TARGET_HARD_FLOAT"
ca7f5001 3357 "{fma|fmadd} %0,%1,%2,%3"
cfb557c4 3358 [(set_attr "type" "dmul")])
1fd4e8c1
RK
3359
3360(define_insn ""
cd2b37d9
RK
3361 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3362 (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
3363 (match_operand:DF 2 "gpc_reg_operand" "f"))
3364 (match_operand:DF 3 "gpc_reg_operand" "f")))]
d14a6d05 3365 "TARGET_HARD_FLOAT"
ca7f5001 3366 "{fms|fmsub} %0,%1,%2,%3"
cfb557c4 3367 [(set_attr "type" "dmul")])
1fd4e8c1
RK
3368
3369(define_insn ""
cd2b37d9
RK
3370 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3371 (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
3372 (match_operand:DF 2 "gpc_reg_operand" "f"))
3373 (match_operand:DF 3 "gpc_reg_operand" "f"))))]
d14a6d05 3374 "TARGET_HARD_FLOAT"
ca7f5001 3375 "{fnma|fnmadd} %0,%1,%2,%3"
cfb557c4 3376 [(set_attr "type" "dmul")])
1fd4e8c1
RK
3377
3378(define_insn ""
cd2b37d9
RK
3379 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3380 (neg:DF (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
3381 (match_operand:DF 2 "gpc_reg_operand" "f"))
3382 (match_operand:DF 3 "gpc_reg_operand" "f"))))]
d14a6d05 3383 "TARGET_HARD_FLOAT"
ca7f5001 3384 "{fnms|fnmsub} %0,%1,%2,%3"
cfb557c4 3385 [(set_attr "type" "dmul")])
ca7f5001
RK
3386
3387(define_insn "sqrtdf2"
3388 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3389 (sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
d14a6d05 3390 "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT"
ca7f5001
RK
3391 "fsqrt %0,%1"
3392 [(set_attr "type" "dsqrt")])
b77dfefc 3393
94d7001a
RK
3394;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
3395;; fsel instruction and some auxiliary computations. Then we just have a
3396;; single DEFINE_INSN for fsel and the define_splits to make them if made by
8e871c05 3397;; combine.
b77dfefc 3398
8e871c05
RK
3399(define_expand "maxdf3"
3400 [(set (match_dup 3)
3401 (minus:DF (match_operand:DF 1 "gpc_reg_operand" "")
3402 (match_operand:DF 2 "gpc_reg_operand" "")))
3403 (set (match_operand:DF 0 "gpc_reg_operand" "")
3404 (if_then_else:DF (ge (match_dup 3)
3405 (const_int 0))
3406 (match_dup 1)
3407 (match_dup 2)))]
d14a6d05 3408 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3409 "
3410{ operands[3] = gen_reg_rtx (DFmode); }")
b77dfefc 3411
8e871c05
RK
3412(define_split
3413 [(set (match_operand:DF 0 "gpc_reg_operand" "")
3414 (smax:DF (match_operand:DF 1 "gpc_reg_operand" "")
f63184ac 3415 (match_operand:DF 2 "gpc_reg_operand" "")))
8e871c05 3416 (clobber (match_operand:DF 3 "gpc_reg_operand" ""))]
d14a6d05 3417 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3418 [(set (match_dup 3)
3419 (minus:DF (match_dup 1) (match_dup 2)))
a81bd72f 3420 (set (match_dup 0)
8e871c05
RK
3421 (if_then_else:DF (ge (match_dup 3)
3422 (const_int 0))
3423 (match_dup 1)
3424 (match_dup 2)))]
3425 "")
b77dfefc 3426
8e871c05
RK
3427(define_expand "mindf3"
3428 [(set (match_dup 3)
3429 (minus:DF (match_operand:DF 2 "gpc_reg_operand" "")
3430 (match_operand:DF 1 "gpc_reg_operand" "")))
3431 (set (match_operand:DF 0 "gpc_reg_operand" "")
3432 (if_then_else:DF (ge (match_dup 3)
3433 (const_int 0))
3434 (match_dup 1)
3435 (match_dup 2)))]
d14a6d05 3436 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3437 "
3438{ operands[3] = gen_reg_rtx (DFmode); }")
b77dfefc 3439
8e871c05
RK
3440(define_split
3441 [(set (match_operand:DF 0 "gpc_reg_operand" "")
3442 (smin:DF (match_operand:DF 1 "gpc_reg_operand" "")
f63184ac 3443 (match_operand:DF 2 "gpc_reg_operand" "")))
8e871c05 3444 (clobber (match_operand:DF 3 "gpc_reg_operand" ""))]
d14a6d05 3445 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3446 [(set (match_dup 3)
3447 (minus:DF (match_dup 2) (match_dup 1)))
a81bd72f 3448 (set (match_dup 0)
8e871c05
RK
3449 (if_then_else:DF (ge (match_dup 3)
3450 (const_int 0))
3451 (match_dup 1)
3452 (match_dup 2)))]
3453 "")
b77dfefc 3454
94d7001a
RK
3455(define_expand "movdfcc"
3456 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3457 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3458 (match_operand:DF 2 "gpc_reg_operand" "f")
3459 (match_operand:DF 3 "gpc_reg_operand" "f")))]
d14a6d05 3460 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
94d7001a
RK
3461 "
3462{
3463 rtx temp, op0, op1;
3464 enum rtx_code code = GET_CODE (operands[1]);
3465 if (! rs6000_compare_fp_p)
3466 FAIL;
3467 switch (code)
3468 {
3469 case GE: case EQ: case NE:
3470 op0 = rs6000_compare_op0;
3471 op1 = rs6000_compare_op1;
3472 break;
3473 case GT:
3474 op0 = rs6000_compare_op1;
3475 op1 = rs6000_compare_op0;
3476 temp = operands[2]; operands[2] = operands[3]; operands[3] = temp;
3477 break;
3478 case LE:
3479 op0 = rs6000_compare_op1;
3480 op1 = rs6000_compare_op0;
3481 break;
3482 case LT:
3483 op0 = rs6000_compare_op0;
3484 op1 = rs6000_compare_op1;
3485 temp = operands[2]; operands[2] = operands[3]; operands[3] = temp;
3486 break;
3487 default:
3488 FAIL;
3489 }
3490 if (GET_MODE (rs6000_compare_op0) == DFmode)
3491 {
3492 temp = gen_reg_rtx (DFmode);
3493 emit_insn (gen_subdf3 (temp, op0, op1));
3494 emit_insn (gen_fseldfdf4 (operands[0], temp, operands[2], operands[3]));
3495 if (code == EQ)
3496 {
3497 emit_insn (gen_negdf2 (temp, temp));
3498 emit_insn (gen_fseldfdf4 (operands[0], temp, operands[0], operands[3]));
3499 }
3500 if (code == NE)
3501 {
3502 emit_insn (gen_negdf2 (temp, temp));
3503 emit_insn (gen_fseldfdf4 (operands[0], temp, operands[3], operands[0]));
3504 }
3505 }
3506 else
3507 {
3508 temp = gen_reg_rtx (SFmode);
3509 emit_insn (gen_subsf3 (temp, op0, op1));
3510 emit_insn (gen_fselsfdf4 (operands[0], temp, operands[2], operands[3]));
3511 if (code == EQ)
3512 {
3513 emit_insn (gen_negsf2 (temp, temp));
3514 emit_insn (gen_fselsfdf4 (operands[0], temp, operands[0], operands[3]));
3515 }
3516 if (code == NE)
3517 {
3518 emit_insn (gen_negsf2 (temp, temp));
3519 emit_insn (gen_fselsfdf4 (operands[0], temp, operands[3], operands[0]));
3520 }
3521 }
3522 DONE;
3523}")
d56d506a 3524
94d7001a 3525(define_insn "fseldfdf4"
8e871c05
RK
3526 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3527 (if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "f")
3528 (const_int 0))
3529 (match_operand:DF 2 "gpc_reg_operand" "f")
3530 (match_operand:DF 3 "gpc_reg_operand" "f")))]
d14a6d05 3531 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
8e871c05
RK
3532 "fsel %0,%1,%2,%3"
3533 [(set_attr "type" "fp")])
d56d506a 3534
94d7001a
RK
3535(define_insn "fselsfdf4"
3536 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3537 (if_then_else:DF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
3538 (const_int 0))
3539 (match_operand:DF 2 "gpc_reg_operand" "f")
3540 (match_operand:DF 3 "gpc_reg_operand" "f")))]
3541 "TARGET_PPC_GFXOPT"
3542 "fsel %0,%1,%2,%3"
3543 [(set_attr "type" "fp")])
1fd4e8c1
RK
3544\f
3545;; Conversions to and from floating-point.
802a0058 3546
1fd4e8c1 3547(define_expand "floatsidf2"
802a0058
MM
3548 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
3549 (float:DF (match_operand:SI 1 "gpc_reg_operand" "")))
3550 (use (match_dup 2))
3551 (use (match_dup 3))
208c89ce 3552 (clobber (match_dup 4))
a7df97e6 3553 (clobber (match_dup 5))
802a0058 3554 (clobber (reg:DF 76))])]
dc4f83ca 3555 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
1fd4e8c1
RK
3556 "
3557{
802a0058
MM
3558 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
3559 operands[3] = force_reg (DFmode, rs6000_float_const (\"4503601774854144\", DFmode));
208c89ce 3560 operands[4] = gen_reg_rtx (SImode);
a7df97e6 3561 operands[5] = gen_reg_rtx (Pmode);
1fd4e8c1
RK
3562}")
3563
802a0058
MM
3564(define_insn "*floatsidf2_internal"
3565 [(set (match_operand:DF 0 "gpc_reg_operand" "=&f")
3566 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
3567 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
3568 (use (match_operand:DF 3 "gpc_reg_operand" "f"))
208c89ce 3569 (clobber (match_operand:SI 4 "gpc_reg_operand" "=r"))
a7df97e6 3570 (clobber (match_operand:SI 5 "gpc_reg_operand" "=b"))
802a0058
MM
3571 (clobber (reg:DF 76))]
3572 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
3573 "#"
a7df97e6 3574 [(set_attr "length" "24")])
802a0058
MM
3575
3576(define_split
dbe3df29 3577 [(set (match_operand:DF 0 "gpc_reg_operand" "")
802a0058
MM
3578 (float:DF (match_operand:SI 1 "gpc_reg_operand" "")))
3579 (use (match_operand:SI 2 "gpc_reg_operand" ""))
3580 (use (match_operand:DF 3 "gpc_reg_operand" ""))
208c89ce 3581 (clobber (match_operand:SI 4 "gpc_reg_operand" ""))
a7df97e6 3582 (clobber (match_operand:SI 5 "gpc_reg_operand" ""))
802a0058
MM
3583 (clobber (reg:DF 76))]
3584 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
3585 [(set (match_dup 4)
208c89ce 3586 (xor:SI (match_dup 1)
a7df97e6
MM
3587 (match_dup 6)))
3588 (set (match_dup 5)
3589 (unspec [(const_int 0)] 11))
3590 (set (match_dup 7)
3591 (unspec [(match_dup 4)
3592 (match_dup 5)] 12)) ;; low word
3593 (set (match_dup 7)
3594 (unspec [(match_dup 2)
3595 (match_dup 5)
3596 (match_dup 7)] 13)) ;; high word
802a0058 3597 (set (match_dup 0)
a7df97e6
MM
3598 (unspec [(match_dup 7)
3599 (match_dup 5)] 14))
802a0058
MM
3600 (set (match_dup 0)
3601 (minus:DF (match_dup 0)
3602 (match_dup 3)))]
208c89ce
MM
3603 "
3604{
a7df97e6
MM
3605 operands[6] = GEN_INT (0x80000000);
3606 operands[7] = gen_rtx (REG, DFmode, FPMEM_REGNUM);
208c89ce 3607}")
802a0058
MM
3608
3609(define_expand "floatunssidf2"
3610 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
3611 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "")))
3612 (use (match_dup 2))
3613 (use (match_dup 3))
a7df97e6 3614 (clobber (match_dup 4))
802a0058 3615 (clobber (reg:DF 76))])]
dc4f83ca 3616 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
1fd4e8c1
RK
3617 "
3618{
802a0058
MM
3619 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
3620 operands[3] = force_reg (DFmode, rs6000_float_const (\"4503599627370496\", DFmode));
a7df97e6 3621 operands[4] = gen_reg_rtx (Pmode);
1fd4e8c1
RK
3622}")
3623
802a0058
MM
3624(define_insn "*floatunssidf2_internal"
3625 [(set (match_operand:DF 0 "gpc_reg_operand" "=&f")
3626 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
3627 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
3628 (use (match_operand:DF 3 "gpc_reg_operand" "f"))
a7df97e6 3629 (clobber (match_operand:SI 4 "gpc_reg_operand" "=b"))
802a0058 3630 (clobber (reg:DF 76))]
dbe3df29 3631 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
802a0058 3632 "#"
a7df97e6 3633 [(set_attr "length" "20")])
802a0058
MM
3634
3635(define_split
3636 [(set (match_operand:DF 0 "gpc_reg_operand" "")
3637 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "")))
3638 (use (match_operand:SI 2 "gpc_reg_operand" ""))
3639 (use (match_operand:DF 3 "gpc_reg_operand" ""))
a7df97e6 3640 (clobber (match_operand:SI 4 "gpc_reg_operand" "=b"))
802a0058
MM
3641 (clobber (reg:DF 76))]
3642 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
3643 [(set (match_dup 4)
a7df97e6
MM
3644 (unspec [(const_int 0)] 11))
3645 (set (match_dup 5)
3646 (unspec [(match_dup 1)
3647 (match_dup 4)] 12)) ;; low word
3648 (set (match_dup 5)
3649 (unspec [(match_dup 2)
3650 (match_dup 4)
3651 (match_dup 5)] 13)) ;; high word
802a0058 3652 (set (match_dup 0)
a7df97e6
MM
3653 (unspec [(match_dup 5)
3654 (reg:SI 1)] 14))
802a0058
MM
3655 (set (match_dup 0)
3656 (minus:DF (match_dup 0)
3657 (match_dup 3)))]
a7df97e6 3658 "operands[5] = gen_rtx (REG, DFmode, FPMEM_REGNUM);")
802a0058 3659
a7df97e6
MM
3660;; Load up scratch register with base address + offset if needed
3661(define_insn "*floatsidf2_loadaddr"
3662 [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
3663 (unspec [(const_int 0)] 11))]
3664 "TARGET_HARD_FLOAT"
3665 "*
3666{
3667 if (rs6000_fpmem_offset > 32760)
3668 {
3669 rtx xop[3];
3670
3671 xop[0] = operands[0];
3672 xop[1] = (frame_pointer_needed) ? frame_pointer_rtx : stack_pointer_rtx;
170e0690 3673 xop[2] = GEN_INT ((rs6000_fpmem_offset >> 16) + ((rs6000_fpmem_offset & 0x8000) >> 15));
538bb158 3674 output_asm_insn (\"{cau|addis} %0,%1,%2\", xop);
a7df97e6
MM
3675 }
3676 else if (rs6000_fpmem_offset < 0)
3677 abort ();
3678
3679 return \"\";
3680}"
3681 [(set_attr "length" "4")])
802a0058
MM
3682
3683(define_insn "*floatsidf2_store1"
3684 [(set (reg:DF 76)
3685 (unspec [(match_operand:SI 0 "gpc_reg_operand" "r")
a7df97e6 3686 (match_operand:SI 1 "gpc_reg_operand" "r")] 12))]
802a0058
MM
3687 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
3688 "*
dbe3df29 3689{
a7df97e6
MM
3690 rtx indx;
3691
3692 if (rs6000_fpmem_offset > 32760)
3693 indx = operands[1];
3694 else if (frame_pointer_needed)
3695 indx = frame_pointer_rtx;
3696 else
3697 indx = stack_pointer_rtx;
3698
3699 operands[2] = gen_rtx (MEM, SImode,
802a0058 3700 gen_rtx (PLUS, Pmode,
a7df97e6 3701 indx,
170e0690 3702 GEN_INT ((((rs6000_fpmem_offset & 0xffff) ^ 0x8000) - 0x8000)
802a0058 3703 + ((WORDS_BIG_ENDIAN != 0) * 4))));
c283c989 3704
a7df97e6 3705 return \"{st|stw} %0,%2\";
802a0058
MM
3706}"
3707 [(set_attr "type" "store")])
3708
3709(define_insn "*floatsidf2_store2"
3710 [(set (reg:DF 76)
3711 (unspec [(match_operand:SI 0 "gpc_reg_operand" "r")
a7df97e6
MM
3712 (match_operand:SI 1 "gpc_reg_operand" "r")
3713 (reg:DF 76)] 13))]
802a0058
MM
3714 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
3715 "*
3716{
a7df97e6
MM
3717 rtx indx;
3718
3719 if (rs6000_fpmem_offset > 32760)
3720 indx = operands[1];
3721 else if (frame_pointer_needed)
3722 indx = frame_pointer_rtx;
3723 else
3724 indx = stack_pointer_rtx;
3725
3726 operands[2] = gen_rtx (MEM, SImode,
802a0058 3727 gen_rtx (PLUS, Pmode,
a7df97e6 3728 indx,
170e0690 3729 GEN_INT ((((rs6000_fpmem_offset & 0xffff) ^ 0x8000) - 0x8000)
802a0058
MM
3730 + ((WORDS_BIG_ENDIAN == 0) * 4))));
3731
a7df97e6 3732 return \"{st|stw} %0,%2\";
802a0058
MM
3733}"
3734 [(set_attr "type" "store")])
3735
3736(define_insn "*floatsidf2_load"
3737 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3738 (unspec [(reg:DF 76)
a7df97e6 3739 (match_operand:SI 1 "gpc_reg_operand" "b")] 14))]
802a0058
MM
3740 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
3741 "*
3742{
a7df97e6 3743 rtx indx;
f6968f59 3744 HOST_WIDE_INT offset = rs6000_fpmem_offset;
a7df97e6
MM
3745
3746 if (rs6000_fpmem_offset > 32760)
f6968f59
MM
3747 {
3748 indx = operands[1];
170e0690 3749 offset = (((offset & 0xffff) ^ 0x8000) - 0x8000);
f6968f59 3750 }
a7df97e6
MM
3751 else if (frame_pointer_needed)
3752 indx = frame_pointer_rtx;
3753 else
3754 indx = stack_pointer_rtx;
3755
3756 operands[2] = gen_rtx (MEM, SImode,
f6968f59 3757 gen_rtx (PLUS, Pmode, indx, GEN_INT (offset)));
802a0058 3758
a7df97e6 3759 return \"lfd %0,%2\";
802a0058
MM
3760}"
3761 [(set_attr "type" "fpload")])
1fd4e8c1 3762
1fd4e8c1 3763(define_expand "fix_truncdfsi2"
802a0058
MM
3764 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
3765 (fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))
3766 (clobber (match_dup 2))
a7df97e6
MM
3767 (clobber (match_dup 3))
3768 (clobber (match_dup 4))])]
d14a6d05 3769 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
3770 "
3771{
802a0058 3772 if (!TARGET_POWER2 && !TARGET_POWERPC)
8ffd9c51
RK
3773 {
3774 emit_insn (gen_trunc_call (operands[0], operands[1],
3775 gen_rtx (SYMBOL_REF, Pmode, RS6000_ITRUNC)));
3776 DONE;
3777 }
802a0058
MM
3778
3779 operands[2] = gen_reg_rtx (DImode);
a7df97e6
MM
3780 operands[3] = gen_reg_rtx (Pmode);
3781 operands[4] = gen_rtx (REG, DImode, FPMEM_REGNUM);
1fd4e8c1
RK
3782}")
3783
802a0058
MM
3784(define_insn "*fix_truncdfsi2_internal"
3785 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3786 (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))
3787 (clobber (match_operand:DI 2 "gpc_reg_operand" "=f"))
a7df97e6 3788 (clobber (match_operand:SI 3 "gpc_reg_operand" "=b"))
802a0058
MM
3789 (clobber (reg:DI 76))]
3790 "TARGET_HARD_FLOAT"
3791 "#"
3792 [(set_attr "length" "12")])
3793
3794(define_split
3795 [(set (match_operand:SI 0 "gpc_reg_operand" "")
3796 (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))
3797 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
a7df97e6 3798 (clobber (match_operand:SI 3 "gpc_reg_operand" ""))
802a0058
MM
3799 (clobber (reg:DI 76))]
3800 "TARGET_HARD_FLOAT"
3801 [(set (match_dup 2)
3802 (sign_extend:DI (fix:SI (match_operand:DF 1 "gpc_reg_operand" ""))))
3803 (set (match_dup 3)
a7df97e6
MM
3804 (unspec [(const_int 0)] 11))
3805 (set (match_dup 4)
802a0058 3806 (unspec [(match_dup 2)
a7df97e6 3807 (match_dup 3)] 15))
802a0058 3808 (set (match_operand:SI 0 "gpc_reg_operand" "")
a7df97e6
MM
3809 (unspec [(match_dup 4)
3810 (match_dup 3)] 16))]
3811 "operands[4] = gen_rtx (REG, DImode, FPMEM_REGNUM);")
802a0058
MM
3812
3813(define_insn "*fctiwz"
8ffd9c51 3814 [(set (match_operand:DI 0 "gpc_reg_operand" "=f")
802a0058 3815 (sign_extend:DI (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))))]
d14a6d05 3816 "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT"
8ffd9c51
RK
3817 "{fcirz|fctiwz} %0,%1"
3818 [(set_attr "type" "fp")])
deb9225a 3819
802a0058
MM
3820(define_insn "*fix_truncdfsi2_store"
3821 [(set (reg:DI 76)
3822 (unspec [(match_operand:DI 0 "gpc_reg_operand" "f")
a7df97e6 3823 (match_operand:SI 1 "gpc_reg_operand" "b")] 15))]
802a0058
MM
3824 "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT"
3825 "*
3826{
a7df97e6
MM
3827 rtx indx;
3828
3829 if (rs6000_fpmem_offset > 32760)
3830 indx = operands[1];
3831 else if (frame_pointer_needed)
3832 indx = frame_pointer_rtx;
3833 else
3834 indx = stack_pointer_rtx;
3835
3836 operands[2] = gen_rtx (MEM, DFmode,
802a0058 3837 gen_rtx (PLUS, Pmode,
a7df97e6 3838 indx,
eaf1bcf1
MM
3839 GEN_INT ((((rs6000_fpmem_offset & 0xffff)
3840 ^ 0x8000) - 0x8000))));
802a0058 3841
170e0690 3842 return \"stfd %0,%w2\";
802a0058
MM
3843}"
3844 [(set_attr "type" "fpstore")])
3845
3846(define_insn "*fix_truncdfsi2_load"
3847 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3848 (unspec [(reg:DI 76)
a7df97e6 3849 (match_operand:SI 1 "gpc_reg_operand" "b")] 16))]
802a0058
MM
3850 "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT"
3851 "*
3852{
a7df97e6
MM
3853 rtx indx;
3854
3855 if (rs6000_fpmem_offset > 32760)
3856 indx = operands[1];
3857 else if (frame_pointer_needed)
3858 indx = frame_pointer_rtx;
3859 else
3860 indx = stack_pointer_rtx;
3861
3862 operands[2] = gen_rtx (MEM, DFmode,
802a0058 3863 gen_rtx (PLUS, Pmode,
a7df97e6 3864 indx,
170e0690 3865 GEN_INT ((((rs6000_fpmem_offset & 0xffff) ^ 0x8000) - 0x8000)
a7df97e6 3866 + ((WORDS_BIG_ENDIAN) ? 4 : 0))));
802a0058 3867
a7df97e6 3868 return \"{l|lwz} %0,%2\";
802a0058
MM
3869}"
3870 [(set_attr "type" "load")])
3871
1fd4e8c1 3872(define_expand "fixuns_truncdfsi2"
cd2b37d9 3873 [(set (match_operand:SI 0 "gpc_reg_operand" "")
b542afe9 3874 (unsigned_fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))]
d14a6d05 3875 "! TARGET_POWER2 && ! TARGET_POWERPC && TARGET_HARD_FLOAT"
1fd4e8c1
RK
3876 "
3877{
3878 emit_insn (gen_trunc_call (operands[0], operands[1],
3c64f04b 3879 gen_rtx (SYMBOL_REF, Pmode, RS6000_UITRUNC)));
1fd4e8c1
RK
3880 DONE;
3881}")
3882
1fd4e8c1
RK
3883(define_expand "trunc_call"
3884 [(parallel [(set (match_operand:SI 0 "" "")
b542afe9 3885 (fix:SI (match_operand:DF 1 "" "")))
1fd4e8c1 3886 (use (match_operand:SI 2 "" ""))])]
d14a6d05 3887 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
3888 "
3889{
3890 rtx insns = gen_trunc_call_rtl (operands[0], operands[1], operands[2]);
3891 rtx first = XVECEXP (insns, 0, 0);
3892 rtx last = XVECEXP (insns, 0, XVECLEN (insns, 0) - 1);
3893
3894 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
3895 REG_NOTES (first));
3896 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
3897
3898 emit_insn (insns);
3899 DONE;
3900}")
3901
3902(define_expand "trunc_call_rtl"
cd2b37d9 3903 [(set (reg:DF 33) (match_operand:DF 1 "gpc_reg_operand" ""))
1fd4e8c1
RK
3904 (use (reg:DF 33))
3905 (parallel [(set (reg:SI 3)
3906 (call (mem:SI (match_operand 2 "" "")) (const_int 0)))
4697a36c 3907 (use (const_int 0))
1fd4e8c1 3908 (clobber (scratch:SI))])
cd2b37d9 3909 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1 3910 (reg:SI 3))]
d14a6d05 3911 "TARGET_HARD_FLOAT"
1fd4e8c1 3912 "
7e69e155 3913{
1fd4e8c1
RK
3914 rs6000_trunc_used = 1;
3915}")
a473029f
RK
3916
3917(define_insn "floatdidf2"
3918 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3919 (float:DF (match_operand:DI 1 "gpc_reg_operand" "f")))]
d14a6d05 3920 "TARGET_POWERPC64 && TARGET_HARD_FLOAT"
a473029f
RK
3921 "fcfid %0,%1"
3922 [(set_attr "type" "fp")])
3923
3924(define_insn "fix_truncdfdi2"
3925 [(set (match_operand:DI 0 "gpc_reg_operand" "=f")
3926 (fix:DI (match_operand:DF 1 "gpc_reg_operand" "f")))]
d14a6d05 3927 "TARGET_POWERPC64 && TARGET_HARD_FLOAT"
a473029f
RK
3928 "fctidz %0,%1"
3929 [(set_attr "type" "fp")])
1fd4e8c1
RK
3930\f
3931;; Define the DImode operations that can be done in a small number
a6ec530c
RK
3932;; of instructions. The & constraints are to prevent the register
3933;; allocator from allocating registers that overlap with the inputs
3934;; (for example, having an input in 7,8 and an output in 6,7). We
3935;; also allow for the the output being the same as one of the inputs.
3936
266eb58a 3937(define_insn "*adddi3_noppc64"
a6ec530c
RK
3938 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r,r,r")
3939 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,0,0")
3940 (match_operand:DI 2 "reg_or_short_operand" "r,I,r,I")))]
e1f83b4d 3941 "! TARGET_POWERPC64"
0f645302
MM
3942 "*
3943{
3944 if (WORDS_BIG_ENDIAN)
3945 return (GET_CODE (operands[2])) != CONST_INT
3946 ? \"{a|addc} %L0,%L1,%L2\;{ae|adde} %0,%1,%2\"
3947 : \"{ai|addic} %L0,%L1,%2\;{a%G2e|add%G2e} %0,%1\";
3948 else
3949 return (GET_CODE (operands[2])) != CONST_INT
3950 ? \"{a|addc} %0,%1,%2\;{ae|adde} %L0,%L1,%L2\"
3951 : \"{ai|addic} %0,%1,%2\;{a%G2e|add%G2e} %L0,%L1\";
3952}"
b19003d8 3953 [(set_attr "length" "8")])
1fd4e8c1 3954
266eb58a 3955(define_insn "*subdi3_noppc64"
e7e5df70
RK
3956 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r,r,r,r")
3957 (minus:DI (match_operand:DI 1 "reg_or_short_operand" "r,I,0,r,I")
3958 (match_operand:DI 2 "gpc_reg_operand" "r,r,r,0,0")))]
266eb58a 3959 "! TARGET_POWERPC64"
5502823b
RK
3960 "*
3961{
0f645302
MM
3962 if (WORDS_BIG_ENDIAN)
3963 return (GET_CODE (operands[1]) != CONST_INT)
3964 ? \"{sf|subfc} %L0,%L2,%L1\;{sfe|subfe} %0,%2,%1\"
3965 : \"{sfi|subfic} %L0,%L2,%1\;{sf%G1e|subf%G1e} %0,%2\";
3966 else
3967 return (GET_CODE (operands[1]) != CONST_INT)
3968 ? \"{sf|subfc} %0,%2,%1\;{sfe|subfe} %L0,%L2,%L1\"
3969 : \"{sfi|subfic} %0,%2,%1\;{sf%G1e|subf%G1e} %L0,%L2\";
5502823b 3970}"
ca7f5001
RK
3971 [(set_attr "length" "8")])
3972
266eb58a 3973(define_insn "*negdi2_noppc64"
a6ec530c
RK
3974 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
3975 (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))]
51b8fc2c 3976 "! TARGET_POWERPC64"
5502823b
RK
3977 "*
3978{
3979 return (WORDS_BIG_ENDIAN)
3980 ? \"{sfi|subfic} %L0,%L1,0\;{sfze|subfze} %0,%1\"
3981 : \"{sfi|subfic} %0,%1,0\;{sfze|subfze} %L0,%L1\";
3982}"
ca7f5001
RK
3983 [(set_attr "length" "8")])
3984
8ffd9c51
RK
3985(define_expand "mulsidi3"
3986 [(set (match_operand:DI 0 "gpc_reg_operand" "")
3987 (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
3988 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))]
3989 ""
3990 "
3991{
3992 if (! TARGET_POWER && ! TARGET_POWERPC)
3993 {
4c0c634c
MM
3994 emit_move_insn (gen_rtx (REG, SImode, 3), operands[1]);
3995 emit_move_insn (gen_rtx (REG, SImode, 4), operands[2]);
fada905b 3996 emit_insn (gen_mull_call ());
cf27b467
MM
3997 if (WORDS_BIG_ENDIAN)
3998 emit_move_insn (operands[0], gen_rtx (REG, DImode, 3));
3999 else
4000 {
4001 emit_move_insn (operand_subword (operands[0], 0, 0, DImode),
4002 gen_rtx (REG, SImode, 3));
4003 emit_move_insn (operand_subword (operands[0], 1, 0, DImode),
4004 gen_rtx (REG, SImode, 4));
4005 }
8ffd9c51
RK
4006 DONE;
4007 }
4008 else if (TARGET_POWER)
4009 {
4010 emit_insn (gen_mulsidi3_mq (operands[0], operands[1], operands[2]));
4011 DONE;
4012 }
4013}")
deb9225a 4014
8ffd9c51 4015(define_insn "mulsidi3_mq"
cd2b37d9 4016 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
8ffd9c51 4017 (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
cd2b37d9 4018 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))
1fd4e8c1 4019 (clobber (match_scratch:SI 3 "=q"))]
ca7f5001 4020 "TARGET_POWER"
b19003d8 4021 "mul %0,%1,%2\;mfmq %L0"
8ffd9c51
RK
4022 [(set_attr "type" "imul")
4023 (set_attr "length" "8")])
deb9225a 4024
ebedb4dd 4025(define_insn "*mulsidi3_powerpc"
425c176f 4026 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
8ffd9c51
RK
4027 (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
4028 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
425c176f 4029 "TARGET_POWERPC && ! TARGET_POWERPC64"
5502823b
RK
4030 "*
4031{
4032 return (WORDS_BIG_ENDIAN)
4033 ? \"mulhw %0,%1,%2\;mullw %L0,%1,%2\"
4034 : \"mulhw %L0,%1,%2\;mullw %0,%1,%2\";
4035}"
8ffd9c51
RK
4036 [(set_attr "type" "imul")
4037 (set_attr "length" "8")])
deb9225a 4038
ebedb4dd
MM
4039(define_split
4040 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4041 (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
4042 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))]
cf27b467 4043 "TARGET_POWERPC && ! TARGET_POWERPC64 && reload_completed"
ebedb4dd
MM
4044 [(set (match_dup 3)
4045 (truncate:SI
4046 (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
4047 (sign_extend:DI (match_dup 2)))
4048 (const_int 32))))
4049 (set (match_dup 4)
4050 (mult:SI (match_dup 1)
4051 (match_dup 2)))]
4052 "
4053{
4054 int endian = (WORDS_BIG_ENDIAN == 0);
4055 operands[3] = operand_subword (operands[0], endian, 0, DImode);
4056 operands[4] = operand_subword (operands[0], 1 - endian, 0, DImode);
4057}")
4058
8106dc08
MM
4059(define_insn "umulsidi3"
4060 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
4061 (mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
4062 (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
4063 "TARGET_POWERPC && ! TARGET_POWERPC64"
4064 "*
4065{
4066 return (WORDS_BIG_ENDIAN)
4067 ? \"mulhwu %0,%1,%2\;mullw %L0,%1,%2\"
4068 : \"mulhwu %L0,%1,%2\;mullw %0,%1,%2\";
4069}"
4070 [(set_attr "type" "imul")
4071 (set_attr "length" "8")])
4072
ebedb4dd
MM
4073(define_split
4074 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4075 (mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
4076 (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))]
cf27b467 4077 "TARGET_POWERPC && ! TARGET_POWERPC64 && reload_completed"
ebedb4dd
MM
4078 [(set (match_dup 3)
4079 (truncate:SI
4080 (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
4081 (zero_extend:DI (match_dup 2)))
4082 (const_int 32))))
4083 (set (match_dup 4)
4084 (mult:SI (match_dup 1)
4085 (match_dup 2)))]
4086 "
4087{
4088 int endian = (WORDS_BIG_ENDIAN == 0);
4089 operands[3] = operand_subword (operands[0], endian, 0, DImode);
4090 operands[4] = operand_subword (operands[0], 1 - endian, 0, DImode);
4091}")
4092
8ffd9c51
RK
4093(define_expand "smulsi3_highpart"
4094 [(set (match_operand:SI 0 "gpc_reg_operand" "")
4095 (truncate:SI
4096 (lshiftrt:DI (mult:DI (sign_extend:DI
4097 (match_operand:SI 1 "gpc_reg_operand" "%r"))
4098 (sign_extend:DI
4099 (match_operand:SI 2 "gpc_reg_operand" "r")))
4100 (const_int 32))))]
4101 ""
4102 "
4103{
4104 if (! TARGET_POWER && ! TARGET_POWERPC)
4105 {
4106 emit_move_insn (gen_rtx (REG, SImode, 3), operands[1]);
4107 emit_move_insn (gen_rtx (REG, SImode, 4), operands[2]);
fada905b 4108 emit_insn (gen_mulh_call ());
8ffd9c51
RK
4109 emit_move_insn (operands[0], gen_rtx (REG, SImode, 3));
4110 DONE;
4111 }
4112 else if (TARGET_POWER)
4113 {
4114 emit_insn (gen_smulsi3_highpart_mq (operands[0], operands[1], operands[2]));
4115 DONE;
4116 }
4117}")
deb9225a 4118
8ffd9c51
RK
4119(define_insn "smulsi3_highpart_mq"
4120 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4121 (truncate:SI
fada905b
MM
4122 (lshiftrt:DI (mult:DI (sign_extend:DI
4123 (match_operand:SI 1 "gpc_reg_operand" "%r"))
4124 (sign_extend:DI
4125 (match_operand:SI 2 "gpc_reg_operand" "r")))
8ffd9c51
RK
4126 (const_int 32))))
4127 (clobber (match_scratch:SI 3 "=q"))]
4128 "TARGET_POWER"
4129 "mul %0,%1,%2"
4130 [(set_attr "type" "imul")])
deb9225a 4131
fada905b 4132(define_insn ""
8ffd9c51
RK
4133 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4134 (truncate:SI
fada905b
MM
4135 (lshiftrt:DI (mult:DI (sign_extend:DI
4136 (match_operand:SI 1 "gpc_reg_operand" "%r"))
4137 (sign_extend:DI
4138 (match_operand:SI 2 "gpc_reg_operand" "r")))
8ffd9c51
RK
4139 (const_int 32))))]
4140 "TARGET_POWERPC"
4141 "mulhw %0,%1,%2"
4142 [(set_attr "type" "imul")])
deb9225a 4143
266eb58a
DE
4144(define_insn "umulsi3_highpart"
4145 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4146 (truncate:SI
4147 (lshiftrt:DI (mult:DI (zero_extend:DI
4148 (match_operand:SI 1 "gpc_reg_operand" "%r"))
4149 (zero_extend:DI
4150 (match_operand:SI 2 "gpc_reg_operand" "r")))
4151 (const_int 32))))]
4152 "TARGET_POWERPC"
4153 "mulhwu %0,%1,%2"
4154 [(set_attr "type" "imul")])
4155
4156;; If operands 0 and 2 are in the same register, we have a problem. But
4157;; operands 0 and 1 (the usual case) can be in the same register. That's
4158;; why we have the strange constraints below.
4159(define_insn "ashldi3_power"
4160 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,&r")
4161 (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,0,r")
4162 (match_operand:SI 2 "reg_or_cint_operand" "M,i,r,r")))
4163 (clobber (match_scratch:SI 3 "=X,q,q,q"))]
4164 "TARGET_POWER"
4165 "@
4166 {sli|slwi} %0,%L1,%h2\;{cal %L0,0(0)|li %L0,0}
4167 sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2
4168 sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2
4169 sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2"
4170 [(set_attr "length" "8")])
4171
4172(define_insn "lshrdi3_power"
4173 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r,r,&r")
4174 (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,0,r")
4175 (match_operand:SI 2 "reg_or_cint_operand" "M,i,r,r")))
4176 (clobber (match_scratch:SI 3 "=X,q,q,q"))]
4177 "TARGET_POWER"
4178 "@
4179 {cal %0,0(0)|li %0,0}\;{s%A2i|s%A2wi} %L0,%1,%h2
4180 sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2
4181 sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2
4182 sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2"
4183 [(set_attr "length" "8")])
4184
4185;; Shift by a variable amount is too complex to be worth open-coding. We
4186;; just handle shifts by constants.
4187(define_insn "ashrdi3_power"
4188 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4189 (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
4190 (match_operand:SI 2 "const_int_operand" "M,i")))
4191 (clobber (match_scratch:SI 3 "=X,q"))]
4192 "TARGET_POWER"
4193 "@
4194 {srai|srawi} %0,%1,31\;{srai|srawi} %L0,%1,%h2
4195 sraiq %0,%1,%h2\;srliq %L0,%L1,%h2"
4196 [(set_attr "length" "8")])
4197\f
4198;; PowerPC64 DImode operations.
4199
4200(define_expand "adddi3"
4201 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4202 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "")
4203 (match_operand:DI 2 "add_operand" "")))]
4204 ""
4205 "
4206{
4207 if (! TARGET_POWERPC64 && non_add_cint_operand (operands[2], DImode))
4208 FAIL;
4209}")
4210
4211;; Discourage ai/addic because of carry but provide it in an alternative
4212;; allowing register zero as source.
4213
4214(define_insn ""
4215 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,?r,r")
4216 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,b,r,b")
4217 (match_operand:DI 2 "add_operand" "r,I,I,J")))]
4218 "TARGET_POWERPC64"
4219 "@
4220 add %0,%1,%2
4221 addi %0,%1,%2
4222 addic %0,%1,%2
802a0058 4223 addis %0,%1,%v2")
266eb58a
DE
4224
4225(define_insn ""
4226 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
4227 (compare:CC (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
4228 (match_operand:DI 2 "reg_or_short_operand" "r,I"))
4229 (const_int 0)))
4230 (clobber (match_scratch:DI 3 "=r,r"))]
4231 "TARGET_POWERPC64"
4232 "@
4233 add. %3,%1,%2
4234 addic. %3,%1,%2"
4235 [(set_attr "type" "compare")])
4236
4237(define_insn ""
4238 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
4239 (compare:CC (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
4240 (match_operand:DI 2 "reg_or_short_operand" "r,I"))
4241 (const_int 0)))
4242 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4243 (plus:DI (match_dup 1) (match_dup 2)))]
4244 "TARGET_POWERPC64"
4245 "@
4246 add. %0,%1,%2
4247 addic. %0,%1,%2"
4248 [(set_attr "type" "compare")])
4249
4250;; Split an add that we can't do in one insn into two insns, each of which
4251;; does one 16-bit part. This is used by combine. Note that the low-order
4252;; add should be last in case the result gets used in an address.
4253
4254(define_split
4255 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4256 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "")
4257 (match_operand:DI 2 "non_add_cint_operand" "")))]
4258 "TARGET_POWERPC64"
4259 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 3)))
4260 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
4261"
4262{
e6ca2c17
DE
4263 HOST_WIDE_INT low = INTVAL (operands[2]) & 0xffff;
4264 HOST_WIDE_INT high = INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff);
266eb58a
DE
4265
4266 if (low & 0x8000)
e6ca2c17 4267 high+=0x10000, low |= ((HOST_WIDE_INT) -1) << 16;
266eb58a 4268
e6ca2c17
DE
4269 operands[3] = GEN_INT (high);
4270 operands[4] = GEN_INT (low);
266eb58a
DE
4271}")
4272
4273(define_insn "one_cmpldi2"
4274 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4275 (not:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
4276 "TARGET_POWERPC64"
4277 "nor %0,%1,%1")
4278
4279(define_insn ""
4280 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4281 (compare:CC (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4282 (const_int 0)))
4283 (clobber (match_scratch:DI 2 "=r"))]
4284 "TARGET_POWERPC64"
4285 "nor. %2,%1,%1"
4286 [(set_attr "type" "compare")])
4287
4288(define_insn ""
4289 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
4290 (compare:CC (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4291 (const_int 0)))
4292 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4293 (not:DI (match_dup 1)))]
4294 "TARGET_POWERPC64"
d944f453 4295 "nor. %0,%1,%1"
266eb58a
DE
4296 [(set_attr "type" "compare")])
4297
4298(define_insn ""
4299 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4300 (minus:DI (match_operand:DI 1 "reg_or_short_operand" "r,I")
4301 (match_operand:DI 2 "gpc_reg_operand" "r,r")))]
4302 "TARGET_POWERPC64"
4303 "@
4304 subf %0,%2,%1
4305 subfic %0,%2,%1")
4306
4307(define_insn ""
4308 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4309 (compare:CC (minus:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4310 (match_operand:DI 2 "gpc_reg_operand" "r"))
4311 (const_int 0)))
4312 (clobber (match_scratch:DI 3 "=r"))]
4313 "TARGET_POWERPC64"
4314 "subf. %3,%2,%1"
4315 [(set_attr "type" "compare")])
4316
4317(define_insn ""
4318 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4319 (compare:CC (minus:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4320 (match_operand:DI 2 "gpc_reg_operand" "r"))
4321 (const_int 0)))
4322 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4323 (minus:DI (match_dup 1) (match_dup 2)))]
4324 "TARGET_POWERPC64"
4325 "subf. %0,%2,%1"
4326 [(set_attr "type" "compare")])
4327
4328(define_expand "subdi3"
4329 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4330 (minus:DI (match_operand:DI 1 "reg_or_short_operand" "")
4331 (match_operand:DI 2 "reg_or_cint_operand" "")))]
4332 ""
4333 "
4334{
4335 if (GET_CODE (operands[2]) == CONST_INT)
4336 {
4337 emit_insn (gen_adddi3 (operands[0], operands[1],
4338 negate_rtx (DImode, operands[2])));
4339 DONE;
4340 }
4341}")
4342
4343(define_insn "absdi2"
4344 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
4345 (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))
4346 (clobber (match_scratch:DI 2 "=&r,&r"))]
4347 "TARGET_POWERPC64"
4348 "sradi %2,%1,31\;xor %0,%2,%1\;subf %0,%2,%0"
4349 [(set_attr "length" "12")])
4350
4351(define_split
4352 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
4353 (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))
4354 (clobber (match_scratch:DI 2 "=&r,&r"))]
4355 "TARGET_POWERPC64 && reload_completed"
4356 [(set (match_dup 2) (ashiftrt:DI (match_dup 1) (const_int 31)))
4357 (set (match_dup 0) (xor:DI (match_dup 2) (match_dup 1)))
4358 (set (match_dup 0) (minus:DI (match_dup 2) (match_dup 0)))]
4359 "")
4360
4361(define_insn ""
4362 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
4363 (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0"))))
4364 (clobber (match_scratch:DI 2 "=&r,&r"))]
4365 "TARGET_POWERPC64"
4366 "sradi %2,%1,31\;xor %0,%2,%1\;subf %0,%0,%2"
4367 [(set_attr "length" "12")])
4368
4369(define_split
4370 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
4371 (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0"))))
4372 (clobber (match_scratch:DI 2 "=&r,&r"))]
4373 "TARGET_POWERPC64 && reload_completed"
4374 [(set (match_dup 2) (ashiftrt:DI (match_dup 1) (const_int 31)))
4375 (set (match_dup 0) (xor:DI (match_dup 2) (match_dup 1)))
4376 (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 2)))]
4377 "")
4378
4379(define_expand "negdi2"
4380 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4381 (neg:DI (match_operand:DI 1 "gpc_reg_operand" "")))]
4382 ""
4383 "")
4384
4385(define_insn ""
4386 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4387 (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
4388 "TARGET_POWERPC64"
4389 "neg %0,%1")
4390
4391(define_insn ""
4392 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4393 (compare:CC (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4394 (const_int 0)))
4395 (clobber (match_scratch:DI 2 "=r"))]
4396 "TARGET_POWERPC64"
4397 "neg. %2,%1"
4398 [(set_attr "type" "compare")])
4399
4400(define_insn ""
4401 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
4402 (compare:CC (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4403 (const_int 0)))
4404 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4405 (neg:DI (match_dup 1)))]
4406 "TARGET_POWERPC64"
4407 "neg. %0,%1"
4408 [(set_attr "type" "compare")])
4409
4410(define_insn "ffsdi2"
4411 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
4412 (ffs:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
4413 "TARGET_POWERPC64"
4414 "neg %0,%1\;and %0,%0,%1\;cntlzd %0,%0\;subfic %0,%0,64"
4415 [(set_attr "length" "16")])
4416
4417(define_insn "muldi3"
4418 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4419 (mult:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4420 (match_operand:DI 2 "gpc_reg_operand" "r")))]
4421 "TARGET_POWERPC64"
4422 "mulld %0,%1,%2"
4423 [(set_attr "type" "imul")])
4424
4425(define_insn "smuldi3_highpart"
4426 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4427 (truncate:DI
4428 (lshiftrt:TI (mult:TI (sign_extend:TI
4429 (match_operand:DI 1 "gpc_reg_operand" "%r"))
4430 (sign_extend:TI
4431 (match_operand:DI 2 "gpc_reg_operand" "r")))
4432 (const_int 64))))]
4433 "TARGET_POWERPC64"
4434 "mulhd %0,%1,%2"
4435 [(set_attr "type" "imul")])
4436
4437(define_insn "umuldi3_highpart"
4438 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4439 (truncate:DI
4440 (lshiftrt:TI (mult:TI (zero_extend:TI
4441 (match_operand:DI 1 "gpc_reg_operand" "%r"))
4442 (zero_extend:TI
4443 (match_operand:DI 2 "gpc_reg_operand" "r")))
4444 (const_int 64))))]
4445 "TARGET_POWERPC64"
4446 "mulhdu %0,%1,%2"
4447 [(set_attr "type" "imul")])
4448
4449(define_expand "divdi3"
4450 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4451 (div:DI (match_operand:DI 1 "gpc_reg_operand" "")
4452 (match_operand:DI 2 "reg_or_cint_operand" "")))]
4453 "TARGET_POWERPC64"
4454 "
4455{
4456 if (GET_CODE (operands[2]) == CONST_INT
4457 && exact_log2 (INTVAL (operands[2])) >= 0)
4458 ;
4459 else
4460 operands[2] = force_reg (DImode, operands[2]);
4461}")
4462
4463(define_expand "moddi3"
4464 [(use (match_operand:DI 0 "gpc_reg_operand" ""))
4465 (use (match_operand:DI 1 "gpc_reg_operand" ""))
4466 (use (match_operand:DI 2 "reg_or_cint_operand" ""))]
4467 "TARGET_POWERPC64"
4468 "
4469{
4470 int i = exact_log2 (INTVAL (operands[2]));
4471 rtx temp1;
4472 rtx temp2;
4473
4474 if (GET_CODE (operands[2]) != CONST_INT || i < 0)
4475 FAIL;
4476
4477 temp1 = gen_reg_rtx (DImode);
4478 temp2 = gen_reg_rtx (DImode);
4479
4480 emit_insn (gen_divdi3 (temp1, operands[1], operands[2]));
4481 emit_insn (gen_ashldi3 (temp2, temp1, GEN_INT (i)));
4482 emit_insn (gen_subdi3 (operands[0], operands[1], temp2));
4483 DONE;
4484}")
4485
4486(define_insn ""
4487 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4488 (div:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4489 (match_operand:DI 2 "const_int_operand" "N")))]
4490 "TARGET_POWERPC64 && exact_log2 (INTVAL (operands[2])) >= 0"
4491 "sradi %0,%1,%p2\;addze %0,%0"
4492 [(set_attr "length" "8")])
4493
4494(define_insn ""
4495 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4496 (compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4497 (match_operand:DI 2 "const_int_operand" "N"))
4498 (const_int 0)))
4499 (clobber (match_scratch:DI 3 "=r"))]
4500 "TARGET_POWERPC64 && exact_log2 (INTVAL (operands[2])) >= 0"
4501 "sradi %3,%1,%p2\;addze. %3,%3"
4502 [(set_attr "type" "compare")
4503 (set_attr "length" "8")])
4504
4505(define_insn ""
4506 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4507 (compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4508 (match_operand:DI 2 "const_int_operand" "N"))
4509 (const_int 0)))
4510 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4511 (div:DI (match_dup 1) (match_dup 2)))]
4512 "TARGET_POWERPC64 && exact_log2 (INTVAL (operands[2])) >= 0"
4513 "sradi %0,%1,%p2\;addze. %0,%0"
4514 [(set_attr "type" "compare")
4515 (set_attr "length" "8")])
4516
4517(define_insn ""
4518 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4519 (div:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4520 (match_operand:DI 2 "gpc_reg_operand" "r")))]
4521 "TARGET_POWERPC64"
4522 "divd %0,%1,%2"
4523 [(set_attr "type" "idiv")])
4524
4525(define_insn "udivdi3"
4526 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4527 (udiv:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4528 (match_operand:DI 2 "gpc_reg_operand" "r")))]
4529 "TARGET_POWERPC64"
4530 "divdu %0,%1,%2"
4531 [(set_attr "type" "idiv")])
4532
4533(define_insn "rotldi3"
4534 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4535 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4536 (match_operand:DI 2 "reg_or_cint_operand" "ri")))]
4537 "TARGET_POWERPC64"
a66078ee 4538 "rld%I2cl %0,%1,%H2,0")
266eb58a
DE
4539
4540(define_insn ""
4541 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4542 (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4543 (match_operand:DI 2 "reg_or_cint_operand" "ri"))
4544 (const_int 0)))
4545 (clobber (match_scratch:DI 3 "=r"))]
4546 "TARGET_POWERPC64"
a66078ee 4547 "rld%I2cl. %3,%1,%H2,0"
266eb58a
DE
4548 [(set_attr "type" "delayed_compare")])
4549
4550(define_insn ""
4551 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4552 (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4553 (match_operand:DI 2 "reg_or_cint_operand" "ri"))
4554 (const_int 0)))
4555 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4556 (rotate:DI (match_dup 1) (match_dup 2)))]
4557 "TARGET_POWERPC64"
a66078ee 4558 "rld%I2cl. %0,%1,%H2,0"
266eb58a
DE
4559 [(set_attr "type" "delayed_compare")])
4560
4561(define_expand "ashldi3"
4562 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4563 (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
4564 (match_operand:SI 2 "reg_or_cint_operand" "")))]
4565 "TARGET_POWERPC64 || TARGET_POWER"
4566 "
4567{
4568 if (TARGET_POWERPC64)
4569 ;
4570 else if (TARGET_POWER)
4571 {
4572 emit_insn (gen_ashldi3_power (operands[0], operands[1], operands[2]));
4573 DONE;
4574 }
4575 else
4576 FAIL;
4577}")
4578
4579(define_insn ""
4580 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4581 (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4582 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
4583 "TARGET_POWERPC64"
a66078ee 4584 "sld%I2 %0,%1,%H2"
266eb58a
DE
4585 [(set_attr "length" "8")])
4586
4587(define_insn ""
4588 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4589 (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4590 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
4591 (const_int 0)))
4592 (clobber (match_scratch:DI 3 "=r"))]
4593 "TARGET_POWERPC64"
a66078ee 4594 "sld%I2. %3,%1,%H2"
266eb58a
DE
4595 [(set_attr "type" "delayed_compare")])
4596
4597(define_insn ""
4598 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4599 (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4600 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
4601 (const_int 0)))
4602 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4603 (ashift:DI (match_dup 1) (match_dup 2)))]
4604 "TARGET_POWERPC64"
a66078ee 4605 "sld%I2. %0,%1,%H2"
266eb58a
DE
4606 [(set_attr "type" "delayed_compare")])
4607
4608(define_expand "lshrdi3"
4609 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4610 (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
4611 (match_operand:SI 2 "reg_or_cint_operand" "")))]
4612 "TARGET_POWERPC64 || TARGET_POWER"
4613 "
4614{
4615 if (TARGET_POWERPC64)
4616 ;
4617 else if (TARGET_POWER)
4618 {
4619 emit_insn (gen_lshrdi3_power (operands[0], operands[1], operands[2]));
4620 DONE;
4621 }
4622 else
4623 FAIL;
4624}")
4625
4626(define_insn ""
4627 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4628 (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4629 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
4630 "TARGET_POWERPC64"
a66078ee 4631 "srd%I2 %0,%1,%H2")
266eb58a
DE
4632
4633(define_insn ""
4634 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4635 (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4636 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
4637 (const_int 0)))
4638 (clobber (match_scratch:DI 3 "=r"))]
4639 "TARGET_POWERPC64"
a66078ee 4640 "srd%I2. %3,%1,%H2"
266eb58a
DE
4641 [(set_attr "type" "delayed_compare")])
4642
4643(define_insn ""
4644 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4645 (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4646 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
4647 (const_int 0)))
4648 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4649 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
4650 "TARGET_POWERPC64"
a66078ee 4651 "srd%I2. %0,%1,%H2"
266eb58a
DE
4652 [(set_attr "type" "delayed_compare")])
4653
4654(define_expand "ashrdi3"
4655 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4656 (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
4657 (match_operand:SI 2 "reg_or_cint_operand" "")))]
4658 "TARGET_POWERPC64 || TARGET_POWER"
4659 "
4660{
4661 if (TARGET_POWERPC64)
4662 ;
4663 else if (TARGET_POWER && GET_CODE (operands[2]) == CONST_INT)
4664 {
4665 emit_insn (gen_ashrdi3_power (operands[0], operands[1], operands[2]));
4666 DONE;
4667 }
4668 else
4669 FAIL;
4670}")
4671
4672(define_insn ""
4673 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4674 (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4675 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
4676 "TARGET_POWERPC64"
375490e0 4677 "srad%I2 %0,%1,%H2")
266eb58a
DE
4678
4679(define_insn ""
4680 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4681 (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4682 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
4683 (const_int 0)))
4684 (clobber (match_scratch:DI 3 "=r"))]
4685 "TARGET_POWERPC64"
375490e0 4686 "srad%I2. %3,%1,%H2"
266eb58a
DE
4687 [(set_attr "type" "delayed_compare")])
4688
4689(define_insn ""
4690 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4691 (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4692 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
4693 (const_int 0)))
4694 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4695 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
4696 "TARGET_POWERPC64"
375490e0 4697 "srad%I2. %0,%1,%H2"
266eb58a
DE
4698 [(set_attr "type" "delayed_compare")])
4699
4700(define_insn "anddi3"
4701 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
4702 (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r")
4703 (match_operand:DI 2 "and_operand" "?r,K,J")))
4704 (clobber (match_scratch:CC 3 "=X,x,x"))]
4705 "TARGET_POWERPC64"
4706 "@
4707 and %0,%1,%2
4708 andi. %0,%1,%b2
4709 andis. %0,%1,%u2")
4710
4711(define_insn ""
4712 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x")
4713 (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r")
4714 (match_operand:DI 2 "and_operand" "r,K,J"))
4715 (const_int 0)))
4716 (clobber (match_scratch:DI 3 "=r,r,r"))]
4717 "TARGET_POWERPC64"
4718 "@
4719 and. %3,%1,%2
4720 andi. %3,%1,%b2
4721 andis. %3,%1,%u2"
4722 [(set_attr "type" "compare,compare,compare")])
4723
4724(define_insn ""
4725 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x")
4726 (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r")
4727 (match_operand:DI 2 "and_operand" "r,K,J"))
4728 (const_int 0)))
4729 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
4730 (and:DI (match_dup 1) (match_dup 2)))]
4731 "TARGET_POWERPC64"
4732 "@
4733 and. %0,%1,%2
4734 andi. %0,%1,%b2
4735 andis. %0,%1,%u2"
4736 [(set_attr "type" "compare,compare,compare")])
4737
4738;; Take a AND with a constant that cannot be done in a single insn and try to
4739;; split it into two insns. This does not verify that the insns are valid
4740;; since this need not be done as combine will do it.
4741
4742(define_split
4743 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4744 (and:DI (match_operand:DI 1 "gpc_reg_operand" "")
4745 (match_operand:DI 2 "non_and_cint_operand" "")))]
4746 "TARGET_POWERPC64"
4747 [(set (match_dup 0) (and:DI (match_dup 1) (match_dup 3)))
4748 (set (match_dup 0) (and:DI (match_dup 0) (match_dup 4)))]
4749 "
4750{
4751 int maskval = INTVAL (operands[2]);
4752 int i, transitions, last_bit_value;
4753 int orig = maskval, first_c = maskval, second_c;
4754
4755 /* We know that MASKVAL must have more than 2 bit-transitions. Start at
4756 the low-order bit and count for the third transition. When we get there,
4757 make a first mask that has everything to the left of that position
4758 a one. Then make the second mask to turn off whatever else is needed. */
4759
4760 for (i = 1, transitions = 0, last_bit_value = maskval & 1; i < 32; i++)
4761 {
4762 if (((maskval >>= 1) & 1) != last_bit_value)
4763 last_bit_value ^= 1, transitions++;
4764
4765 if (transitions > 2)
4766 {
4767 first_c |= (~0) << i;
4768 break;
4769 }
4770 }
4771
4772 second_c = orig | ~ first_c;
4773
4774 operands[3] = gen_rtx (CONST_INT, VOIDmode, first_c);
4775 operands[4] = gen_rtx (CONST_INT, VOIDmode, second_c);
4776}")
4777
4778(define_insn "iordi3"
4779 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
4780 (ior:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r")
4781 (match_operand:DI 2 "logical_operand" "r,K,J")))]
4782 "TARGET_POWERPC64"
4783 "@
4784 or %0,%1,%2
4785 ori %0,%1,%b2
4786 oris %0,%1,%u2")
4787
4788(define_insn ""
4789 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4790 (compare:CC (ior:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4791 (match_operand:DI 2 "gpc_reg_operand" "r"))
4792 (const_int 0)))
4793 (clobber (match_scratch:DI 3 "=r"))]
4794 "TARGET_POWERPC64"
4795 "or. %3,%1,%2"
4796 [(set_attr "type" "compare")])
4797
4798(define_insn ""
4799 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4800 (compare:CC (ior:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4801 (match_operand:DI 2 "gpc_reg_operand" "r"))
4802 (const_int 0)))
4803 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4804 (ior:DI (match_dup 1) (match_dup 2)))]
4805 "TARGET_POWERPC64"
4806 "or. %0,%1,%2"
4807 [(set_attr "type" "compare")])
4808
4809;; Split an IOR that we can't do in one insn into two insns, each of which
4810;; does one 16-bit part. This is used by combine.
4811
4812(define_split
4813 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4814 (ior:DI (match_operand:DI 1 "gpc_reg_operand" "")
4815 (match_operand:DI 2 "non_logical_cint_operand" "")))]
4816 "TARGET_POWERPC64"
4817 [(set (match_dup 0) (ior:DI (match_dup 1) (match_dup 3)))
4818 (set (match_dup 0) (ior:DI (match_dup 0) (match_dup 4)))]
4819"
4820{
4821 operands[3] = gen_rtx (CONST_INT, VOIDmode,
e6ca2c17 4822 INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff));
266eb58a
DE
4823 operands[4] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0xffff);
4824}")
1fd4e8c1 4825
266eb58a
DE
4826(define_insn "xordi3"
4827 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
4828 (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r")
4829 (match_operand:DI 2 "logical_operand" "r,K,J")))]
4830 "TARGET_POWERPC64"
1fd4e8c1 4831 "@
266eb58a
DE
4832 xor %0,%1,%2
4833 xori %0,%1,%b2
4834 xoris %0,%1,%u2")
1fd4e8c1 4835
266eb58a
DE
4836(define_insn ""
4837 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4838 (compare:CC (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4839 (match_operand:DI 2 "gpc_reg_operand" "r"))
4840 (const_int 0)))
4841 (clobber (match_scratch:DI 3 "=r"))]
4842 "TARGET_POWERPC64"
4843 "xor. %3,%1,%2"
4844 [(set_attr "type" "compare")])
1fd4e8c1 4845
266eb58a
DE
4846(define_insn ""
4847 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4848 (compare:CC (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4849 (match_operand:DI 2 "gpc_reg_operand" "r"))
4850 (const_int 0)))
4851 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4852 (xor:DI (match_dup 1) (match_dup 2)))]
4853 "TARGET_POWERPC64"
4854 "xor. %0,%1,%2"
4855 [(set_attr "type" "compare")])
1fd4e8c1 4856
266eb58a
DE
4857;; Split an XOR that we can't do in one insn into two insns, each of which
4858;; does one 16-bit part. This is used by combine.
4859
4860(define_split
4861 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4862 (xor:DI (match_operand:DI 1 "gpc_reg_operand" "")
4863 (match_operand:DI 2 "non_logical_cint_operand" "")))]
4864 "TARGET_POWERPC64"
4865 [(set (match_dup 0) (xor:DI (match_dup 1) (match_dup 3)))
4866 (set (match_dup 0) (xor:DI (match_dup 0) (match_dup 4)))]
4867"
4868{
4869 operands[3] = gen_rtx (CONST_INT, VOIDmode,
4870 INTVAL (operands[2]) & 0xffff0000);
4871 operands[4] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0xffff);
1fd4e8c1
RK
4872}")
4873
2bee0449 4874(define_insn ""
266eb58a
DE
4875 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4876 (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4877 (match_operand:DI 2 "gpc_reg_operand" "r"))))]
4878 "TARGET_POWERPC64"
4879 "eqv %0,%1,%2")
a473029f 4880
266eb58a
DE
4881(define_insn ""
4882 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4883 (compare:CC (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4884 (match_operand:DI 2 "gpc_reg_operand" "r")))
4885 (const_int 0)))
4886 (clobber (match_scratch:DI 3 "=r"))]
4887 "TARGET_POWERPC64"
4888 "eqv. %3,%1,%2"
4889 [(set_attr "type" "compare")])
a473029f 4890
266eb58a
DE
4891(define_insn ""
4892 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4893 (compare:CC (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4894 (match_operand:DI 2 "gpc_reg_operand" "r")))
4895 (const_int 0)))
4896 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4897 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
4898 "TARGET_POWERPC64"
4899 "eqv. %0,%1,%2"
4900 [(set_attr "type" "compare")])
4901
4902(define_insn ""
a473029f 4903 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
266eb58a
DE
4904 (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4905 (match_operand:DI 2 "gpc_reg_operand" "r")))]
a473029f 4906 "TARGET_POWERPC64"
266eb58a 4907 "andc %0,%2,%1")
a473029f 4908
266eb58a
DE
4909(define_insn ""
4910 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4911 (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4912 (match_operand:DI 2 "gpc_reg_operand" "r"))
4913 (const_int 0)))
4914 (clobber (match_scratch:DI 3 "=r"))]
a473029f 4915 "TARGET_POWERPC64"
266eb58a
DE
4916 "andc. %3,%2,%1"
4917 [(set_attr "type" "compare")])
a473029f 4918
266eb58a
DE
4919(define_insn ""
4920 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4921 (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4922 (match_operand:DI 2 "gpc_reg_operand" "r"))
4923 (const_int 0)))
4924 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4925 (and:DI (not:DI (match_dup 1)) (match_dup 2)))]
a473029f 4926 "TARGET_POWERPC64"
266eb58a
DE
4927 "andc. %0,%2,%1"
4928 [(set_attr "type" "compare")])
a473029f 4929
266eb58a 4930(define_insn ""
a473029f 4931 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
266eb58a
DE
4932 (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4933 (match_operand:DI 2 "gpc_reg_operand" "r")))]
a473029f 4934 "TARGET_POWERPC64"
266eb58a 4935 "orc %0,%2,%1")
a473029f 4936
266eb58a
DE
4937(define_insn ""
4938 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4939 (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4940 (match_operand:DI 2 "gpc_reg_operand" "r"))
4941 (const_int 0)))
4942 (clobber (match_scratch:DI 3 "=r"))]
4943 "TARGET_POWERPC64"
4944 "orc. %3,%2,%1"
4945 [(set_attr "type" "compare")])
4946
4947(define_insn ""
4948 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4949 (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4950 (match_operand:DI 2 "gpc_reg_operand" "r"))
4951 (const_int 0)))
4952 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4953 (ior:DI (not:DI (match_dup 1)) (match_dup 2)))]
4954 "TARGET_POWERPC64"
4955 "orc. %0,%2,%1"
4956 [(set_attr "type" "compare")])
4957
4958(define_insn ""
a473029f 4959 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
266eb58a
DE
4960 (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
4961 (not:DI (match_operand:DI 2 "gpc_reg_operand" "r"))))]
a473029f 4962 "TARGET_POWERPC64"
266eb58a 4963 "nand %0,%1,%2")
a473029f 4964
266eb58a
DE
4965(define_insn ""
4966 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4967 (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
4968 (not:DI (match_operand:DI 2 "gpc_reg_operand" "r")))
4969 (const_int 0)))
4970 (clobber (match_scratch:DI 3 "=r"))]
4971 "TARGET_POWERPC64"
4972 "nand. %3,%1,%2"
4973 [(set_attr "type" "compare")])
4974
4975(define_insn ""
4976 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4977 (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
4978 (not:DI (match_operand:DI 2 "gpc_reg_operand" "r")))
4979 (const_int 0)))
4980 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4981 (ior:DI (not:DI (match_dup 1)) (not:DI (match_dup 2))))]
4982 "TARGET_POWERPC64"
4983 "nand. %0,%1,%2"
4984 [(set_attr "type" "compare")])
4985
4986(define_insn ""
a473029f 4987 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
266eb58a
DE
4988 (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
4989 (not:DI (match_operand:DI 2 "gpc_reg_operand" "r"))))]
a473029f 4990 "TARGET_POWERPC64"
266eb58a 4991 "nor %0,%1,%2")
a473029f
RK
4992
4993(define_insn ""
4994 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
266eb58a
DE
4995 (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
4996 (not:DI (match_operand:DI 2 "gpc_reg_operand" "r")))
a473029f
RK
4997 (const_int 0)))
4998 (clobber (match_scratch:DI 3 "=r"))]
4999 "TARGET_POWERPC64"
266eb58a
DE
5000 "nor. %3,%1,%2"
5001 [(set_attr "type" "compare")])
a473029f
RK
5002
5003(define_insn ""
5004 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
266eb58a
DE
5005 (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
5006 (not:DI (match_operand:DI 2 "gpc_reg_operand" "r")))
a473029f
RK
5007 (const_int 0)))
5008 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
266eb58a 5009 (and:DI (not:DI (match_dup 1)) (not:DI (match_dup 2))))]
a473029f 5010 "TARGET_POWERPC64"
266eb58a
DE
5011 "nor. %0,%1,%2"
5012 [(set_attr "type" "compare")])
a473029f 5013\f
1fd4e8c1 5014;; Now define ways of moving data around.
4697a36c
MM
5015
5016;; Elf specific ways of loading addresses for non-PIC code.
5017;; The output of this could be r0, but we limit it to base
5018;; registers, since almost all uses of this will need it
5019;; in a base register shortly.
5020(define_insn "elf_high"
5021 [(set (match_operand:SI 0 "register_operand" "=b")
5022 (high:SI (match_operand 1 "" "")))]
5023 "TARGET_ELF && !TARGET_64BIT"
5024 "{cau|addis} %0,0,%1@ha")
5025
5026(define_insn "elf_low"
5027 [(set (match_operand:SI 0 "register_operand" "=r")
5028 (lo_sum:SI (match_operand:SI 1 "register_operand" "b")
5029 (match_operand 2 "" "")))]
5030 "TARGET_ELF && !TARGET_64BIT"
5031 "{cal %0,%a2@l(%1)|addi %0,%1,%2@l}")
5032
766a866c
MM
5033;; Set up a register with a value from the GOT table
5034
5035(define_expand "movsi_got"
5036 [(set (match_operand:SI 0 "register_operand" "")
5037 (unspec [(match_operand:SI 1 "got_operand" "")
5038 (match_dup 2)] 8))]
58307bcd 5039 "(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) && flag_pic == 1"
766a866c
MM
5040 "
5041{
c4c40373 5042 operands[2] = rs6000_got_register (operands[1]);
766a866c
MM
5043}")
5044
84f414bc 5045(define_insn "*movsi_got_internal"
766a866c
MM
5046 [(set (match_operand:SI 0 "register_operand" "=r")
5047 (unspec [(match_operand:SI 1 "got_operand" "")
5048 (match_operand:SI 2 "register_operand" "b")] 8))]
c81bebd7 5049 "(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) && flag_pic == 1"
766a866c
MM
5050 "{l|lwz} %0,%a1@got(%2)"
5051 [(set_attr "type" "load")])
5052
1fd4e8c1
RK
5053;; For SI, we special-case integers that can't be loaded in one insn. We
5054;; do the load 16-bits at a time. We could do this by loading from memory,
5055;; and this is even supposed to be faster, but it is simpler not to get
5056;; integers in the TOC.
5057(define_expand "movsi"
5058 [(set (match_operand:SI 0 "general_operand" "")
5059 (match_operand:SI 1 "any_operand" ""))]
5060 ""
5061 "
5062{
5063 if (GET_CODE (operands[0]) != REG)
5064 operands[1] = force_reg (SImode, operands[1]);
5065
ef0e171b
RK
5066 /* Convert a move of a CONST_DOUBLE into a CONST_INT */
5067 if (GET_CODE (operands[1]) == CONST_DOUBLE)
5068 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
5069
88228c4b
MM
5070 /* Use default pattern for address of ELF small data */
5071 if (TARGET_ELF
c81bebd7 5072 && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
88228c4b 5073 && (GET_CODE (operands[1]) == SYMBOL_REF || GET_CODE (operands[1]) == CONST)
e98bb982 5074 && small_data_operand (operands[1], SImode))
88228c4b
MM
5075 {
5076 emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
5077 DONE;
5078 }
5079
c81bebd7 5080 if ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
84f414bc 5081 && flag_pic == 1 && got_operand (operands[1], SImode))
766a866c
MM
5082 {
5083 emit_insn (gen_movsi_got (operands[0], operands[1]));
5084 DONE;
5085 }
5086
4697a36c 5087 if (TARGET_ELF && TARGET_NO_TOC && !TARGET_64BIT
461422d5 5088 && !flag_pic
4697a36c
MM
5089 && CONSTANT_P (operands[1])
5090 && GET_CODE (operands[1]) != HIGH
5091 && GET_CODE (operands[1]) != CONST_INT)
5092 {
5093 rtx target = (reload_completed || reload_in_progress)
5094 ? operands[0] : gen_reg_rtx (SImode);
5095
b6c9286a
MM
5096 /* If this is a function address on -mcall-aixdesc or -mcall-nt,
5097 convert it to the address of the descriptor. */
5098 if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
5099 && GET_CODE (operands[1]) == SYMBOL_REF
5100 && XSTR (operands[1], 0)[0] == '.')
5101 {
5102 char *name = XSTR (operands[1], 0);
5103 rtx new_ref;
5104 while (*name == '.')
5105 name++;
5106 new_ref = gen_rtx (SYMBOL_REF, Pmode, name);
5107 CONSTANT_POOL_ADDRESS_P (new_ref) = CONSTANT_POOL_ADDRESS_P (operands[1]);
5108 SYMBOL_REF_FLAG (new_ref) = SYMBOL_REF_FLAG (operands[1]);
5109 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
5110 operands[1] = new_ref;
5111 }
5112
4697a36c
MM
5113 emit_insn (gen_elf_high (target, operands[1]));
5114 emit_insn (gen_elf_low (operands[0], target, operands[1]));
5115 DONE;
5116 }
5117
b6c9286a
MM
5118 if (GET_CODE (operands[1]) == CONST
5119 && DEFAULT_ABI == ABI_NT
5120 && !side_effects_p (operands[0]))
5121 {
5122 rtx const_term = const0_rtx;
5123 rtx sym = eliminate_constant_term (XEXP (operands[1], 0), &const_term);
5124 if (sym && GET_CODE (const_term) == CONST_INT
5125 && (GET_CODE (sym) == SYMBOL_REF || GET_CODE (sym) == LABEL_REF))
5126 {
354b734b
MM
5127 unsigned HOST_WIDE_INT value = INTVAL (const_term);
5128 int new_reg_p = (flag_expensive_optimizations
5129 && !reload_completed
5130 && !reload_in_progress);
5131 rtx tmp1 = (new_reg_p && value != 0) ? gen_reg_rtx (SImode) : operands[0];
5132
5133 emit_insn (gen_movsi (tmp1, sym));
b6c9286a
MM
5134 if (INTVAL (const_term) != 0)
5135 {
b6c9286a 5136 if (value + 0x8000 < 0x10000)
354b734b
MM
5137 emit_insn (gen_addsi3 (operands[0], tmp1, GEN_INT (value)));
5138
b6c9286a
MM
5139 else
5140 {
354b734b
MM
5141 HOST_WIDE_INT high_int = value & (~ (HOST_WIDE_INT) 0xffff);
5142 HOST_WIDE_INT low_int = value & 0xffff;
5143 rtx tmp2 = (!new_reg_p || !low_int) ? operands[0] : gen_reg_rtx (Pmode);
5144
5145 if (low_int & 0x8000)
5146 high_int += 0x10000, low_int |= ((HOST_WIDE_INT) -1) << 16;
b6c9286a 5147
354b734b
MM
5148 emit_insn (gen_addsi3 (tmp2, tmp1, GEN_INT (high_int)));
5149 if (low_int)
5150 emit_insn (gen_addsi3 (operands[0], tmp2, GEN_INT (low_int)));
b6c9286a
MM
5151 }
5152 }
5153 DONE;
5154 }
5155 else
5156 fatal_insn (\"bad address\", operands[1]);
5157 }
5158
5159 if ((!TARGET_WINDOWS_NT || DEFAULT_ABI != ABI_NT)
5160 && CONSTANT_P (operands[1])
4697a36c
MM
5161 && GET_CODE (operands[1]) != CONST_INT
5162 && GET_CODE (operands[1]) != HIGH
78b8d850 5163 && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1]))
b45863ec 5164 {
d302f4f2
MM
5165 /* Emit a USE operation so that the constant isn't deleted if
5166 expensive optimizations are turned on because nobody
e0350319
MM
5167 references it. This should only be done for operands that
5168 contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set.
5169 This should not be done for operands that contain LABEL_REFs.
5170 For now, we just handle the obvious case. */
5171 if (GET_CODE (operands[1]) != LABEL_REF)
5172 emit_insn (gen_rtx (USE, VOIDmode, operands[1]));
d302f4f2 5173
30a4619d
RK
5174 /* If we are to limit the number of things we put in the TOC and
5175 this is a symbol plus a constant we can add in one insn,
abc95ed3 5176 just put the symbol in the TOC and add the constant. Don't do
30a4619d
RK
5177 this if reload is in progress. */
5178 if (GET_CODE (operands[1]) == CONST
5179 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
5180 && GET_CODE (XEXP (operands[1], 0)) == PLUS
5181 && add_operand (XEXP (XEXP (operands[1], 0), 1), SImode)
5182 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
5183 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
5184 && ! side_effects_p (operands[0]))
5185 {
5186 rtx sym = force_const_mem (SImode, XEXP (XEXP (operands[1], 0), 0));
5187 rtx other = XEXP (XEXP (operands[1], 0), 1);
5188
5189 emit_insn (gen_addsi3 (operands[0], force_reg (SImode, sym), other));
5190 DONE;
5191 }
5192
b45863ec
RK
5193 operands[1] = force_const_mem (SImode, operands[1]);
5194 if (! memory_address_p (SImode, XEXP (operands[1], 0))
5195 && ! reload_in_progress)
5196 operands[1] = change_address (operands[1], SImode,
5197 XEXP (operands[1], 0));
5198 }
1fd4e8c1
RK
5199}")
5200
5201(define_insn ""
88228c4b
MM
5202 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,r,r,r,r,r,*q,*c*l,*h")
5203 (match_operand:SI 1 "input_operand" "r,S,T,U,m,r,I,J,n,R,*h,r,r,0"))]
19d5775a
RK
5204 "gpc_reg_operand (operands[0], SImode)
5205 || gpc_reg_operand (operands[1], SImode)"
1fd4e8c1 5206 "@
deb9225a 5207 mr %0,%1
b6c9286a
MM
5208 {l|lwz} %0,[toc]%1(2)
5209 {l|lwz} %0,[toc]%l1(2)
b9442c72 5210 {cal|la} %0,%a1
ca7f5001
RK
5211 {l%U1%X1|lwz%U1%X1} %0,%1
5212 {st%U0%X0|stw%U0%X0} %1,%0
19d5775a 5213 {lil|li} %0,%1
802a0058 5214 {liu|lis} %0,%v1
beaec479 5215 #
57fa6739 5216 {cal|la} %0,%1(%*)
1fd4e8c1 5217 mf%1 %0
5c23c401 5218 mt%0 %1
e76e75bb
RK
5219 mt%0 %1
5220 cror 0,0,0"
b7ff3d82 5221 [(set_attr "type" "*,load,load,*,load,store,*,*,*,*,*,*,mtjmpr,*")
88228c4b 5222 (set_attr "length" "4,4,4,4,4,4,4,4,8,4,4,4,4,4")])
1fd4e8c1 5223
77fa0940
RK
5224;; Split a load of a large constant into the appropriate two-insn
5225;; sequence.
5226
5227(define_split
5228 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5229 (match_operand:SI 1 "const_int_operand" ""))]
5230 "(unsigned) (INTVAL (operands[1]) + 0x8000) >= 0x10000
5231 && (INTVAL (operands[1]) & 0xffff) != 0"
5232 [(set (match_dup 0)
5233 (match_dup 2))
5234 (set (match_dup 0)
5235 (ior:SI (match_dup 0)
5236 (match_dup 3)))]
5237 "
5238{
5239 operands[2] = gen_rtx (CONST_INT, VOIDmode,
5240 INTVAL (operands[1]) & 0xffff0000);
5241 operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0xffff);
5242}")
5243
1fd4e8c1
RK
5244(define_insn ""
5245 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
cd2b37d9 5246 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 5247 (const_int 0)))
cd2b37d9 5248 (set (match_operand:SI 0 "gpc_reg_operand" "=r") (match_dup 1))]
1fd4e8c1 5249 ""
deb9225a 5250 "mr. %0,%1"
1fd4e8c1
RK
5251 [(set_attr "type" "compare")])
5252\f
5253(define_expand "movhi"
5254 [(set (match_operand:HI 0 "general_operand" "")
5255 (match_operand:HI 1 "any_operand" ""))]
5256 ""
5257 "
5258{
5259 if (GET_CODE (operands[0]) != REG)
5260 operands[1] = force_reg (HImode, operands[1]);
5261
5262 if (CONSTANT_P (operands[1]) && GET_CODE (operands[1]) != CONST_INT)
b45863ec
RK
5263 {
5264 operands[1] = force_const_mem (HImode, operands[1]);
5265 if (! memory_address_p (HImode, XEXP (operands[1], 0))
5266 && ! reload_in_progress)
5267 operands[1] = change_address (operands[1], HImode,
5268 XEXP (operands[1], 0));
5269 }
1fd4e8c1
RK
5270}")
5271
5272(define_insn ""
fb81d7ce
RK
5273 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*q,*c*l,*h")
5274 (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,r,0"))]
19d5775a
RK
5275 "gpc_reg_operand (operands[0], HImode)
5276 || gpc_reg_operand (operands[1], HImode)"
1fd4e8c1 5277 "@
deb9225a 5278 mr %0,%1
1fd4e8c1
RK
5279 lhz%U1%X1 %0,%1
5280 sth%U0%X0 %1,%0
19d5775a 5281 {lil|li} %0,%w1
1fd4e8c1 5282 mf%1 %0
e76e75bb 5283 mt%0 %1
fb81d7ce 5284 mt%0 %1
e76e75bb 5285 cror 0,0,0"
b7ff3d82 5286 [(set_attr "type" "*,load,store,*,*,*,mtjmpr,*")])
1fd4e8c1
RK
5287
5288(define_expand "movqi"
5289 [(set (match_operand:QI 0 "general_operand" "")
5290 (match_operand:QI 1 "any_operand" ""))]
5291 ""
5292 "
5293{
5294 if (GET_CODE (operands[0]) != REG)
5295 operands[1] = force_reg (QImode, operands[1]);
5296
5297 if (CONSTANT_P (operands[1]) && GET_CODE (operands[1]) != CONST_INT)
b45863ec
RK
5298 {
5299 operands[1] = force_const_mem (QImode, operands[1]);
5300 if (! memory_address_p (QImode, XEXP (operands[1], 0))
5301 && ! reload_in_progress)
5302 operands[1] = change_address (operands[1], QImode,
5303 XEXP (operands[1], 0));
5304 }
1fd4e8c1
RK
5305}")
5306
5307(define_insn ""
fb81d7ce
RK
5308 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*q,*c*l,*h")
5309 (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,r,0"))]
19d5775a
RK
5310 "gpc_reg_operand (operands[0], QImode)
5311 || gpc_reg_operand (operands[1], QImode)"
1fd4e8c1 5312 "@
deb9225a 5313 mr %0,%1
1fd4e8c1
RK
5314 lbz%U1%X1 %0,%1
5315 stb%U0%X0 %1,%0
19d5775a 5316 {lil|li} %0,%1
1fd4e8c1 5317 mf%1 %0
e76e75bb 5318 mt%0 %1
fb81d7ce 5319 mt%0 %1
e76e75bb 5320 cror 0,0,0"
b7ff3d82 5321 [(set_attr "type" "*,load,store,*,*,*,mtjmpr,*")])
1fd4e8c1
RK
5322\f
5323;; Here is how to move condition codes around. When we store CC data in
5324;; an integer register or memory, we store just the high-order 4 bits.
5325;; This lets us not shift in the most common case of CR0.
5326(define_expand "movcc"
5327 [(set (match_operand:CC 0 "nonimmediate_operand" "")
5328 (match_operand:CC 1 "nonimmediate_operand" ""))]
5329 ""
5330 "")
5331
5332(define_insn ""
5333 [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,y,r,r,r,r,m")
5334 (match_operand:CC 1 "nonimmediate_operand" "y,r,r,x,y,r,m,r"))]
5335 "register_operand (operands[0], CCmode)
5336 || register_operand (operands[1], CCmode)"
5337 "@
5338 mcrf %0,%1
5339 mtcrf 128,%1
ca7f5001 5340 {rlinm|rlwinm} %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;{rlinm|rlwinm} %1,%1,%f0,0xffffffff
1fd4e8c1 5341 mfcr %0
ca7f5001 5342 mfcr %0\;{rlinm|rlwinm} %0,%0,%f1,0xf0000000
deb9225a 5343 mr %0,%1
ca7f5001
RK
5344 {l%U1%X1|lwz%U1%X1} %0,%1
5345 {st%U0%U1|stw%U0%U1} %1,%0"
b7ff3d82 5346 [(set_attr "type" "*,*,*,compare,*,*,load,store")
b19003d8 5347 (set_attr "length" "*,*,12,*,8,*,*,*")])
1fd4e8c1 5348\f
e52e05ca
MM
5349;; For floating-point, we normally deal with the floating-point registers
5350;; unless -msoft-float is used. The sole exception is that parameter passing
5351;; can produce floating-point values in fixed-point registers. Unless the
5352;; value is a simple constant or already in memory, we deal with this by
5353;; allocating memory and copying the value explicitly via that memory location.
1fd4e8c1
RK
5354(define_expand "movsf"
5355 [(set (match_operand:SF 0 "nonimmediate_operand" "")
5356 (match_operand:SF 1 "any_operand" ""))]
5357 ""
5358 "
5359{
5360 /* If we are called from reload, we might be getting a SUBREG of a hard
5361 reg. So expand it. */
5362 if (GET_CODE (operands[0]) == SUBREG
5363 && GET_CODE (SUBREG_REG (operands[0])) == REG
5364 && REGNO (SUBREG_REG (operands[0])) < FIRST_PSEUDO_REGISTER)
5365 operands[0] = alter_subreg (operands[0]);
5366 if (GET_CODE (operands[1]) == SUBREG
5367 && GET_CODE (SUBREG_REG (operands[1])) == REG
5368 && REGNO (SUBREG_REG (operands[1])) < FIRST_PSEUDO_REGISTER)
5369 operands[1] = alter_subreg (operands[1]);
5370
3b7f6cca
MM
5371 if (TARGET_SOFT_FLOAT && GET_CODE (operands[0]) == MEM)
5372 operands[1] = force_reg (SFmode, operands[1]);
5373
5374 else if (TARGET_HARD_FLOAT)
1fd4e8c1 5375 {
e52e05ca 5376 if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 32)
1fd4e8c1 5377 {
e52e05ca
MM
5378 /* If this is a store to memory or another integer register do the
5379 move directly. Otherwise store to a temporary stack slot and
5380 load from there into a floating point register. */
5381
5382 if (GET_CODE (operands[0]) == MEM
5383 || (GET_CODE (operands[0]) == REG
5384 && (REGNO (operands[0]) < 32
5385 || (reload_in_progress
5386 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))))
5387 {
5388 emit_move_insn (operand_subword (operands[0], 0, 0, SFmode),
5389 operand_subword (operands[1], 0, 0, SFmode));
5390 DONE;
5391 }
5392 else
5393 {
5394 rtx stack_slot = assign_stack_temp (SFmode, 4, 0);
5395
5396 emit_move_insn (stack_slot, operands[1]);
5397 emit_move_insn (operands[0], stack_slot);
5398 DONE;
5399 }
f6ba0600 5400 }
1fd4e8c1 5401
e52e05ca 5402 if (GET_CODE (operands[0]) == MEM)
f2974b07 5403 {
e52e05ca
MM
5404 /* If operands[1] is a register, it may have double-precision data
5405 in it, so truncate it to single precision. We need not do
5406 this for POWERPC. */
455350f4
RK
5407 if (! TARGET_POWERPC && TARGET_HARD_FLOAT
5408 && GET_CODE (operands[1]) == REG)
e52e05ca 5409 {
455350f4
RK
5410 rtx newreg
5411 = reload_in_progress ? operands[1] : gen_reg_rtx (SFmode);
5412 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
e52e05ca
MM
5413 operands[1] = newreg;
5414 }
5415
5416 operands[1] = force_reg (SFmode, operands[1]);
f2974b07
RK
5417 }
5418
e52e05ca
MM
5419 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) < 32)
5420 {
5421 if (GET_CODE (operands[1]) == MEM
1fd4e8c1 5422#if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT && ! defined(REAL_IS_NOT_DOUBLE)
e52e05ca 5423 || GET_CODE (operands[1]) == CONST_DOUBLE
1fd4e8c1 5424#endif
e52e05ca
MM
5425 || (GET_CODE (operands[1]) == REG
5426 && (REGNO (operands[1]) < 32
5427 || (reload_in_progress
5428 && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER))))
5429 {
5430 emit_move_insn (operand_subword (operands[0], 0, 0, SFmode),
5431 operand_subword (operands[1], 0, 0, SFmode));
5432 DONE;
5433 }
5434 else
5435 {
5436 rtx stack_slot = assign_stack_temp (SFmode, 4, 0);
5437
5438 emit_move_insn (stack_slot, operands[1]);
5439 emit_move_insn (operands[0], stack_slot);
5440 DONE;
5441 }
f6ba0600 5442 }
1fd4e8c1
RK
5443 }
5444
c4c40373 5445 if (CONSTANT_P (operands[1]) && TARGET_HARD_FLOAT)
1fd4e8c1
RK
5446 {
5447 operands[1] = force_const_mem (SFmode, operands[1]);
5448 if (! memory_address_p (SFmode, XEXP (operands[1], 0))
5449 && ! reload_in_progress)
5450 operands[1] = change_address (operands[1], SFmode,
5451 XEXP (operands[1], 0));
5452 }
5453}")
5454
1fd4e8c1 5455(define_split
cd2b37d9 5456 [(set (match_operand:SF 0 "gpc_reg_operand" "")
c4c40373
MM
5457 (match_operand:SF 1 "const_double_operand" ""))]
5458 "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], SFmode) <= 1 && REGNO (operands[0]) <= 31"
5459 [(set (match_dup 2) (match_dup 3))]
685f3906
DE
5460 "
5461{
5462 long l;
5463 REAL_VALUE_TYPE rv;
5464
5465 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
5466 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
c4c40373
MM
5467
5468 operands[2] = gen_rtx (SUBREG, SImode, operands[0], 0);
5469 operands[3] = GEN_INT(l);
685f3906 5470}")
7e69e155 5471
c4c40373
MM
5472(define_split
5473 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5474 (match_operand:SF 1 "const_double_operand" ""))]
5475 "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], SFmode) == 2 && REGNO (operands[0]) <= 31"
5476 [(set (match_dup 2) (match_dup 3))
5477 (set (match_dup 2) (ior:SI (match_dup 2) (match_dup 4)))]
5478 "
5479{
5480 long l;
5481 REAL_VALUE_TYPE rv;
5482
5483 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
5484 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
5485
5486 operands[2] = gen_rtx (SUBREG, SImode, operands[0], 0);
5487 operands[3] = GEN_INT(l & 0xffff0000);
5488 operands[4] = GEN_INT(l & 0x0000ffff);
5489}")
5490
5491(define_insn "*movsf_hardfloat"
5492 [(set (match_operand:SF 0 "fp_reg_or_mem_operand" "=f,f,m,!r,!r")
5493 (match_operand:SF 1 "input_operand" "f,m,f,G,Fn"))]
d14a6d05
MM
5494 "(gpc_reg_operand (operands[0], SFmode)
5495 || gpc_reg_operand (operands[1], SFmode)) && TARGET_HARD_FLOAT"
1fd4e8c1
RK
5496 "@
5497 fmr %0,%1
5498 lfs%U1%X1 %0,%1
c4c40373
MM
5499 stfs%U0%X0 %1,%0
5500 #
5501 #"
5502 [(set_attr "type" "fp,fpload,fpstore,*,*")
5503 (set_attr "length" "4,4,4,4,8")])
d14a6d05 5504
c4c40373
MM
5505(define_insn "*movsf_softfloat"
5506 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,r")
5507 (match_operand:SF 1 "input_operand" "r,m,r,I,J,R,G,Fn"))]
d14a6d05
MM
5508 "(gpc_reg_operand (operands[0], SFmode)
5509 || gpc_reg_operand (operands[1], SFmode)) && TARGET_SOFT_FLOAT"
5510 "@
5511 mr %0,%1
5512 {l%U1%X1|lwz%U1%X1} %0,%1
5513 {st%U0%X0|stw%U0%X0} %1,%0
5514 {lil|li} %0,%1
802a0058 5515 {liu|lis} %0,%v1
c4c40373
MM
5516 {cal|la} %0,%1(%*)
5517 #
5518 #"
5519 [(set_attr "type" "*,load,store,*,*,*,*,*")
5520 (set_attr "length" "4,4,4,4,4,4,4,8")])
d14a6d05 5521
1fd4e8c1
RK
5522\f
5523(define_expand "movdf"
5524 [(set (match_operand:DF 0 "nonimmediate_operand" "")
5525 (match_operand:DF 1 "any_operand" ""))]
5526 ""
5527 "
5528{
e7113111
RK
5529 if (GET_CODE (operands[0]) != REG)
5530 operands[1] = force_reg (DFmode, operands[1]);
1fd4e8c1 5531
08075ead
DE
5532 /* Stores between FPR and any non-FPR registers must go through a
5533 temporary stack slot. */
5534
5535 if (TARGET_POWERPC64
5536 && GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG
5537 && ((FP_REGNO_P (REGNO (operands[0]))
5538 && ! FP_REGNO_P (REGNO (operands[1])))
5539 || (FP_REGNO_P (REGNO (operands[1]))
5540 && ! FP_REGNO_P (REGNO (operands[0])))))
5541 {
5542 rtx stack_slot = assign_stack_temp (DFmode, 8, 0);
5543
5544 emit_move_insn (stack_slot, operands[1]);
5545 emit_move_insn (operands[0], stack_slot);
5546 DONE;
5547 }
5548
e7113111 5549 if (CONSTANT_P (operands[1]) && ! easy_fp_constant (operands[1], DFmode))
1fd4e8c1
RK
5550 {
5551 operands[1] = force_const_mem (DFmode, operands[1]);
5552 if (! memory_address_p (DFmode, XEXP (operands[1], 0))
5553 && ! reload_in_progress)
5554 operands[1] = change_address (operands[1], DFmode,
5555 XEXP (operands[1], 0));
5556 }
e7113111 5557}")
1fd4e8c1
RK
5558
5559(define_split
cd2b37d9 5560 [(set (match_operand:DF 0 "gpc_reg_operand" "")
c4c40373
MM
5561 (match_operand:DF 1 "const_int_operand" ""))]
5562 "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DFmode) <= 1 && REGNO (operands[0]) <= 31"
5563 [(set (match_dup 2) (match_dup 4))
5564 (set (match_dup 3) (match_dup 1))]
5565 "
5566{
5567 operands[2] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0);
5568 operands[3] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0);
5569 operands[4] = (INTVAL (operands[1]) & 0x80000000) ? constm1_rtx : const0_rtx;
5570}")
5571
5572(define_split
5573 [(set (match_operand:DF 0 "gpc_reg_operand" "")
5574 (match_operand:DF 1 "const_int_operand" ""))]
5575 "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DFmode) >= 2 && REGNO (operands[0]) <= 31"
5576 [(set (match_dup 3) (match_dup 5))
5577 (set (match_dup 2) (match_dup 4))
5578 (set (match_dup 3) (ior:SI (match_dup 3) (match_dup 6)))]
5579 "
5580{
5581 HOST_WIDE_INT value = INTVAL (operands[1]);
5582 operands[2] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0);
5583 operands[3] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0);
5584 operands[4] = (value & 0x80000000) ? constm1_rtx : const0_rtx;
5585 operands[5] = GEN_INT (value & 0xffff0000);
5586 operands[6] = GEN_INT (value & 0x0000ffff);
5587}")
5588
5589(define_split
5590 [(set (match_operand:DF 0 "gpc_reg_operand" "")
5591 (match_operand:DF 1 "const_double_operand" ""))]
5592 "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DFmode) <= 2 && REGNO (operands[0]) <= 31"
5593 [(set (match_dup 2) (match_dup 4))
5594 (set (match_dup 3) (match_dup 5))]
5595 "
5596{
5597 operands[2] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0);
5598 operands[3] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0);
f6968f59
MM
5599
5600#ifdef HOST_WORDS_BIG_ENDIAN
5601 operands[4] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
5602 operands[5] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
5603#else
5604 operands[4] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
5605 operands[5] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
5606#endif
c4c40373
MM
5607}")
5608
5609(define_split
5610 [(set (match_operand:DF 0 "gpc_reg_operand" "")
5611 (match_operand:DF 1 "const_double_operand" ""))]
5612 "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DFmode) == 3 && REGNO (operands[0]) <= 31"
5613 [(set (match_dup 2) (match_dup 4))
5614 (set (match_dup 3) (match_dup 5))
5615 (set (match_dup 2) (ior:SI (match_dup 2) (match_dup 6)))]
5616 "
5617{
a651f222
MM
5618 HOST_WIDE_INT high;
5619 HOST_WIDE_INT low;
c4c40373
MM
5620 rtx high_reg = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0);
5621 rtx low_reg = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0);
5622
f6968f59
MM
5623#ifdef HOST_WORDS_BIG_ENDIAN
5624 high = CONST_DOUBLE_LOW (operands[1]);
5625 low = CONST_DOUBLE_HIGH (operands[1]);
5626#else
5627 high = CONST_DOUBLE_HIGH (operands[1]);
5628 low = CONST_DOUBLE_LOW (operands[1]);
5629#endif
a651f222 5630
c4c40373
MM
5631 if (((unsigned HOST_WIDE_INT) (low + 0x8000) < 0x10000)
5632 || (low & 0xffff) == 0)
5633 {
5634 operands[2] = high_reg;
5635 operands[3] = low_reg;
5636 operands[4] = GEN_INT (high & 0xffff0000);
5637 operands[5] = GEN_INT (low);
5638 operands[6] = GEN_INT (high & 0x0000ffff);
5639 }
5640 else
5641 {
5642 operands[2] = low_reg;
5643 operands[3] = high_reg;
5644 operands[4] = GEN_INT (low & 0xffff0000);
5645 operands[5] = GEN_INT (high);
5646 operands[6] = GEN_INT (low & 0x0000ffff);
5647 }
5648}")
5649
5650(define_split
5651 [(set (match_operand:DF 0 "gpc_reg_operand" "")
5652 (match_operand:DF 1 "const_double_operand" ""))]
5653 "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DFmode) >= 4 && REGNO (operands[0]) <= 31"
5654 [(set (match_dup 2) (match_dup 4))
5655 (set (match_dup 3) (match_dup 5))
5656 (set (match_dup 2) (ior:SI (match_dup 2) (match_dup 6)))
5657 (set (match_dup 3) (ior:SI (match_dup 3) (match_dup 7)))]
1fd4e8c1 5658 "
c4c40373 5659{
f6968f59
MM
5660 HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5661 HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
c4c40373
MM
5662
5663 operands[2] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0);
5664 operands[3] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0);
5665 operands[4] = GEN_INT (high & 0xffff0000);
5666 operands[5] = GEN_INT (low & 0xffff0000);
5667 operands[6] = GEN_INT (high & 0x0000ffff);
5668 operands[7] = GEN_INT (low & 0x0000ffff);
5669}")
e7113111 5670
efc08378
DE
5671(define_split
5672 [(set (match_operand:DF 0 "gpc_reg_operand" "")
685f3906 5673 (match_operand:DF 1 "easy_fp_constant" ""))]
efc08378
DE
5674 "TARGET_64BIT && reload_completed && REGNO (operands[0]) <= 31"
5675 [(set (subreg:DI (match_dup 0) 0) (subreg:DI (match_dup 1) 0))]
5676 "")
5677
4eae5fe1
RK
5678;; Don't have reload use general registers to load a constant. First,
5679;; it might not work if the output operand has is the equivalent of
5680;; a non-offsettable memref, but also it is less efficient than loading
5681;; the constant into an FP register, since it will probably be used there.
5682;; The "??" is a kludge until we can figure out a more reasonable way
5683;; of handling these non-offsettable values.
c4c40373
MM
5684(define_insn "*movdf_hardfloat32"
5685 [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,o,!r,!r,!r,f,f,m")
5686 (match_operand:DF 1 "input_operand" "r,o,r,G,H,F,f,m,f"))]
dc4f83ca
MM
5687 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
5688 && (register_operand (operands[0], DFmode)
5689 || register_operand (operands[1], DFmode))"
e7113111
RK
5690 "*
5691{
5692 switch (which_alternative)
5693 {
5694 case 0:
5695 /* We normally copy the low-numbered register first. However, if
5696 the first register operand 0 is the same as the second register of
5697 operand 1, we must copy in the opposite order. */
5698 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
deb9225a 5699 return \"mr %L0,%L1\;mr %0,%1\";
e7113111 5700 else
deb9225a 5701 return \"mr %0,%1\;mr %L0,%L1\";
e7113111
RK
5702 case 1:
5703 /* If the low-address word is used in the address, we must load it
5704 last. Otherwise, load it first. Note that we cannot have
5705 auto-increment in that case since the address register is known to be
5706 dead. */
5707 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
5708 operands [1], 0))
ca7f5001 5709 return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
e7113111 5710 else
ca7f5001 5711 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
e7113111 5712 case 2:
ca7f5001 5713 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
e7113111 5714 case 3:
e7113111 5715 case 4:
e7113111 5716 case 5:
c4c40373 5717 return \"#\";
e7113111 5718 case 6:
c4c40373
MM
5719 return \"fmr %0,%1\";
5720 case 7:
5721 return \"lfd%U1%X1 %0,%1\";
5722 case 8:
e7113111
RK
5723 return \"stfd%U0%X0 %1,%0\";
5724 }
5725}"
c4c40373
MM
5726 [(set_attr "type" "*,load,store,*,*,*,fp,fpload,fpstore")
5727 (set_attr "length" "8,8,8,8,12,16,*,*,*")])
51b8fc2c 5728
c4c40373
MM
5729(define_insn "*movdf_softfloat32"
5730 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,o,r,r,r")
5731 (match_operand:DF 1 "input_operand" "r,o,r,G,H,F"))]
dc4f83ca
MM
5732 "! TARGET_POWERPC64 && TARGET_SOFT_FLOAT
5733 && (register_operand (operands[0], DFmode)
5734 || register_operand (operands[1], DFmode))"
5735 "*
5736{
5737 switch (which_alternative)
5738 {
5739 case 0:
5740 /* We normally copy the low-numbered register first. However, if
5741 the first register operand 0 is the same as the second register of
5742 operand 1, we must copy in the opposite order. */
5743 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
5744 return \"mr %L0,%L1\;mr %0,%1\";
5745 else
5746 return \"mr %0,%1\;mr %L0,%L1\";
5747 case 1:
5748 /* If the low-address word is used in the address, we must load it
5749 last. Otherwise, load it first. Note that we cannot have
5750 auto-increment in that case since the address register is known to be
5751 dead. */
5752 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
5753 operands [1], 0))
5754 return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
5755 else
5756 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
5757 case 2:
5758 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
5759 case 3:
c4c40373
MM
5760 case 4:
5761 case 5:
dc4f83ca
MM
5762 return \"#\";
5763 }
5764}"
c4c40373
MM
5765 [(set_attr "type" "*,load,store,*,*,*")
5766 (set_attr "length" "8,8,8,8,12,16")])
dc4f83ca 5767
c4c40373
MM
5768(define_insn "*movdf_hardfloat64"
5769 [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,o,!r,!r,!r,f,f,m")
5770 (match_operand:DF 1 "input_operand" "r,o,r,G,H,F,f,m,f"))]
dc4f83ca
MM
5771 "TARGET_POWERPC64 && TARGET_HARD_FLOAT
5772 && (register_operand (operands[0], DFmode)
5773 || register_operand (operands[1], DFmode))"
51b8fc2c 5774 "@
3d5570cb
RK
5775 mr %0,%1
5776 ld%U1%X1 %0,%1
96bb8ed3 5777 std%U0%X0 %1,%0
3d5570cb 5778 #
c4c40373
MM
5779 #
5780 #
3d5570cb 5781 fmr %0,%1
f63184ac 5782 lfd%U1%X1 %0,%1
3d5570cb 5783 stfd%U0%X0 %1,%0"
c4c40373
MM
5784 [(set_attr "type" "*,load,store,*,*,*,fp,fpload,fpstore")
5785 (set_attr "length" "4,4,4,8,12,16,4,4,4")])
dc4f83ca 5786
c4c40373
MM
5787(define_insn "*movdf_softfloat64"
5788 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,o,r,r,r")
5789 (match_operand:DF 1 "input_operand" "r,o,r,G,H,F"))]
dc4f83ca
MM
5790 "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
5791 && (register_operand (operands[0], DFmode)
5792 || register_operand (operands[1], DFmode))"
5793 "@
5794 mr %0,%1
5795 ld%U1%X1 %0,%1
96bb8ed3 5796 std%U0%X0 %1,%0
c4c40373
MM
5797 #
5798 #
dc4f83ca 5799 #"
c4c40373
MM
5800 [(set_attr "type" "*,load,store,*,*,*")
5801 (set_attr "length" "*,*,*,8,12,16")])
1fd4e8c1
RK
5802\f
5803;; Next come the multi-word integer load and store and the load and store
5804;; multiple insns.
5805(define_expand "movdi"
5806 [(set (match_operand:DI 0 "general_operand" "")
e6ca2c17 5807 (match_operand:DI 1 "any_operand" ""))]
1fd4e8c1
RK
5808 ""
5809 "
5810{
e6ca2c17 5811 if (GET_CODE (operands[0]) != REG)
6b6ccd10
RK
5812 operands[1] = force_reg (DImode, operands[1]);
5813
4e74d8ec
MM
5814 if (TARGET_64BIT
5815 && (GET_CODE (operands[1]) == CONST_DOUBLE
5816 || GET_CODE (operands[1]) == CONST_INT))
1fd4e8c1 5817 {
6b6ccd10
RK
5818 HOST_WIDE_INT low;
5819 HOST_WIDE_INT high;
5820
5821 if (GET_CODE (operands[1]) == CONST_DOUBLE)
5822 {
f6968f59
MM
5823 low = CONST_DOUBLE_LOW (operands[1]);
5824 high = CONST_DOUBLE_HIGH (operands[1]);
6b6ccd10 5825 }
e8d791dd
DE
5826 else
5827#if HOST_BITS_PER_WIDE_INT == 32
6b6ccd10
RK
5828 {
5829 low = INTVAL (operands[1]);
5830 high = (low < 0) ? ~0 : 0;
5831 }
e8d791dd 5832#else
e6ca2c17
DE
5833 {
5834 low = INTVAL (operands[1]) & 0xffffffff;
f4558646 5835 high = (HOST_WIDE_INT) INTVAL (operands[1]) >> 32;
e6ca2c17 5836 }
e8d791dd 5837#endif
6b6ccd10 5838
4e74d8ec
MM
5839 if (high)
5840 {
5841 emit_move_insn (operands[0], GEN_INT (high));
5842 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT(32)));
5843 if (low)
5844 {
5845 HOST_WIDE_INT low_low = low & 0xffff;
5846 HOST_WIDE_INT low_high = low & (~ (HOST_WIDE_INT) 0xffff);
5847 if (low_high)
5848 emit_insn (gen_iordi3 (operands[0], operands[0],
5849 GEN_INT (low_high)));
5850 if (low_low)
5851 emit_insn (gen_iordi3 (operands[0], operands[0],
5852 GEN_INT (low_low)));
5853 }
5854 DONE;
5855 }
1fd4e8c1 5856 }
062284d8 5857
a473029f
RK
5858 /* Stores between FPR and any non-FPR registers must go through a
5859 temporary stack slot. */
5860
5861 if (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG
5862 && ((FP_REGNO_P (REGNO (operands[0]))
5863 && ! FP_REGNO_P (REGNO (operands[1])))
5864 || (FP_REGNO_P (REGNO (operands[1]))
5865 && ! FP_REGNO_P (REGNO (operands[0])))))
5866 {
425c176f 5867 rtx stack_slot = assign_stack_temp (DImode, 8, 0);
a473029f 5868
a473029f
RK
5869 emit_move_insn (stack_slot, operands[1]);
5870 emit_move_insn (operands[0], stack_slot);
5871 DONE;
5872 }
1fd4e8c1
RK
5873}")
5874
c4c40373 5875(define_insn "*movdi_32"
4e74d8ec
MM
5876 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,f,f,m,r,r,r,r,r")
5877 (match_operand:DI 1 "input_operand" "r,m,r,f,m,f,IJK,n,G,H,F"))]
5878 "TARGET_32BIT
5879 && (gpc_reg_operand (operands[0], DImode)
5880 || gpc_reg_operand (operands[1], DImode))"
1fd4e8c1
RK
5881 "*
5882{
5883 switch (which_alternative)
5884 {
5885 case 0:
5886 /* We normally copy the low-numbered register first. However, if
5887 the first register operand 0 is the same as the second register of
5888 operand 1, we must copy in the opposite order. */
5889 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
deb9225a 5890 return \"mr %L0,%L1\;mr %0,%1\";
1fd4e8c1 5891 else
deb9225a 5892 return \"mr %0,%1\;mr %L0,%L1\";
1fd4e8c1
RK
5893 case 1:
5894 /* If the low-address word is used in the address, we must load it
5895 last. Otherwise, load it first. Note that we cannot have
5896 auto-increment in that case since the address register is known to be
5897 dead. */
5898 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
5899 operands [1], 0))
ca7f5001 5900 return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
1fd4e8c1 5901 else
ca7f5001 5902 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
1fd4e8c1 5903 case 2:
ca7f5001 5904 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
8ffd9c51
RK
5905 case 3:
5906 return \"fmr %0,%1\";
5907 case 4:
5908 return \"lfd%U1%X1 %0,%1\";
5909 case 5:
5910 return \"stfd%U0%X0 %1,%0\";
4e74d8ec
MM
5911 case 6:
5912 case 7:
5913 case 8:
5914 case 9:
5915 case 10:
5916 return \"#\";
1fd4e8c1
RK
5917 }
5918}"
4e74d8ec
MM
5919 [(set_attr "type" "*,load,store,fp,fpload,fpstore,*,*,*,*,*")
5920 (set_attr "length" "8,8,8,*,*,*,8,12,8,12,16")])
5921
5922(define_split
5923 [(set (match_operand:DI 0 "gpc_reg_operand" "")
5924 (match_operand:DI 1 "const_int_operand" ""))]
5925 "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DImode) <= 1"
5926 [(set (match_dup 2) (match_dup 4))
5927 (set (match_dup 3) (match_dup 1))]
5928 "
5929{
5930 operands[2] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0);
5931 operands[3] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0);
5932 operands[4] = (INTVAL (operands[1]) & 0x80000000) ? constm1_rtx : const0_rtx;
5933}")
5934
5935(define_split
5936 [(set (match_operand:DI 0 "gpc_reg_operand" "")
5937 (match_operand:DI 1 "const_int_operand" ""))]
5938 "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DImode) >= 2"
5939 [(set (match_dup 3) (match_dup 5))
5940 (set (match_dup 2) (match_dup 4))
5941 (set (match_dup 3) (ior:SI (match_dup 3) (match_dup 6)))]
5942 "
5943{
5944 HOST_WIDE_INT value = INTVAL (operands[1]);
5945 operands[2] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0);
5946 operands[3] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0);
5947 operands[4] = (value & 0x80000000) ? constm1_rtx : const0_rtx;
5948 operands[5] = GEN_INT (value & 0xffff0000);
5949 operands[6] = GEN_INT (value & 0x0000ffff);
5950}")
5951
5952(define_split
5953 [(set (match_operand:DI 0 "gpc_reg_operand" "")
5954 (match_operand:DI 1 "const_double_operand" ""))]
5955 "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DImode) <= 2"
5956 [(set (match_dup 2) (match_dup 4))
5957 (set (match_dup 3) (match_dup 5))]
5958 "
5959{
5960 operands[2] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0);
5961 operands[3] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0);
f6968f59
MM
5962 operands[4] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
5963 operands[5] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
4e74d8ec
MM
5964}")
5965
5966(define_split
5967 [(set (match_operand:DI 0 "gpc_reg_operand" "")
5968 (match_operand:DI 1 "const_double_operand" ""))]
5969 "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DImode) == 3"
5970 [(set (match_dup 2) (match_dup 4))
5971 (set (match_dup 3) (match_dup 5))
5972 (set (match_dup 2) (ior:SI (match_dup 2) (match_dup 6)))]
5973 "
5974{
f6968f59
MM
5975 HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5976 HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5977 rtx high_reg = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0);
5978 rtx low_reg = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0);
a651f222 5979
4e74d8ec
MM
5980 if (((unsigned HOST_WIDE_INT) (low + 0x8000) < 0x10000)
5981 || (low & 0xffff) == 0)
5982 {
5983 operands[2] = high_reg;
5984 operands[3] = low_reg;
5985 operands[4] = GEN_INT (high & 0xffff0000);
5986 operands[5] = GEN_INT (low);
5987 operands[6] = GEN_INT (high & 0x0000ffff);
5988 }
5989 else
5990 {
5991 operands[2] = low_reg;
5992 operands[3] = high_reg;
5993 operands[4] = GEN_INT (low & 0xffff0000);
5994 operands[5] = GEN_INT (high);
5995 operands[6] = GEN_INT (low & 0x0000ffff);
5996 }
5997}")
5998
5999(define_split
6000 [(set (match_operand:DI 0 "gpc_reg_operand" "")
6001 (match_operand:DI 1 "const_double_operand" ""))]
6002 "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DImode) >= 4"
6003 [(set (match_dup 2) (match_dup 4))
6004 (set (match_dup 3) (match_dup 5))
6005 (set (match_dup 2) (ior:SI (match_dup 2) (match_dup 6)))
6006 (set (match_dup 3) (ior:SI (match_dup 3) (match_dup 7)))]
6007 "
6008{
f6968f59
MM
6009 HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
6010 HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
4e74d8ec
MM
6011
6012 operands[2] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0);
6013 operands[3] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0);
6014 operands[4] = GEN_INT (high & 0xffff0000);
6015 operands[5] = GEN_INT (low & 0xffff0000);
6016 operands[6] = GEN_INT (high & 0x0000ffff);
6017 operands[7] = GEN_INT (low & 0x0000ffff);
6018}")
51b8fc2c 6019
c4c40373 6020(define_insn "*movdi_64"
e6ca2c17 6021 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,f,f,m,r,*h,*h")
4e74d8ec
MM
6022 (match_operand:DI 1 "input_operand" "r,m,r,I,J,nF,R,f,m,f,*h,r,0"))]
6023 "TARGET_64BIT
6024 && (gpc_reg_operand (operands[0], DImode)
6025 || gpc_reg_operand (operands[1], DImode))"
51b8fc2c 6026 "@
3d5570cb
RK
6027 mr %0,%1
6028 ld%U1%X1 %0,%1
96bb8ed3 6029 std%U0%X0 %1,%0
3d5570cb 6030 li %0,%1
802a0058 6031 lis %0,%v1
e6ca2c17 6032 #
57fa6739 6033 {cal|la} %0,%1(%*)
3d5570cb
RK
6034 fmr %0,%1
6035 lfd%U1%X1 %0,%1
6036 stfd%U0%X0 %1,%0
6037 mf%1 %0
08075ead
DE
6038 mt%0 %1
6039 cror 0,0,0"
b7ff3d82 6040 [(set_attr "type" "*,load,store,*,*,*,*,fp,fpload,fpstore,*,mtjmpr,*")
e6ca2c17
DE
6041 (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4")])
6042
6043;; Split a load of a large constant into the appropriate five-instruction
6044;; sequence. The expansion in movdi tries to perform the minimum number of
6045;; steps, but here we have to handle anything in a constant number of insns.
6046
6047(define_split
6048 [(set (match_operand:DI 0 "gpc_reg_operand" "")
6049 (match_operand:DI 1 "const_double_operand" ""))]
4e74d8ec 6050 "TARGET_64BIT && num_insns_constant (operands[1], DImode) > 1"
e6ca2c17
DE
6051 [(set (match_dup 0)
6052 (match_dup 2))
6053 (set (match_dup 0)
6054 (ior:DI (match_dup 0)
6055 (match_dup 3)))
6056 (set (match_dup 0)
6057 (ashift:DI (match_dup 0)
6058 (const_int 32)))
6059 (set (match_dup 0)
6060 (ior:DI (match_dup 0)
6061 (match_dup 4)))
6062 (set (match_dup 0)
6063 (ior:DI (match_dup 0)
6064 (match_dup 5)))]
6065 "
6066{
6067 HOST_WIDE_INT low;
6068 HOST_WIDE_INT high;
6069
6070 if (GET_CODE (operands[1]) == CONST_DOUBLE)
6071 {
f6968f59
MM
6072 low = CONST_DOUBLE_LOW (operands[1]);
6073 high = CONST_DOUBLE_HIGH (operands[1]);
e6ca2c17 6074 }
e8d791dd
DE
6075 else
6076#if HOST_BITS_PER_WIDE_INT == 32
e6ca2c17
DE
6077 {
6078 low = INTVAL (operands[1]);
6079 high = (low < 0) ? ~0 : 0;
6080 }
e8d791dd 6081#else
e6ca2c17
DE
6082 {
6083 low = INTVAL (operands[1]) & 0xffffffff;
f4558646 6084 high = (HOST_WIDE_INT) INTVAL (operands[1]) >> 32;
e6ca2c17 6085 }
e8d791dd 6086#endif
e6ca2c17
DE
6087
6088 if ((high + 0x8000) < 0x10000
6089 && ((low & 0xffff) == 0 || (low & (~ (HOST_WIDE_INT) 0xffff)) == 0))
6090 FAIL;
6091
6092 operands[2] = GEN_INT (high & (~ (HOST_WIDE_INT) 0xffff));
6093 operands[3] = GEN_INT (high & 0xffff);
6094 operands[4] = GEN_INT (low & (~ (HOST_WIDE_INT) 0xffff));
6095 operands[5] = GEN_INT (low & 0xffff);
6096}")
08075ead
DE
6097
6098(define_insn ""
6099 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
6100 (compare:CC (match_operand:DI 1 "gpc_reg_operand" "r")
6101 (const_int 0)))
6102 (set (match_operand:DI 0 "gpc_reg_operand" "=r") (match_dup 1))]
6103 "TARGET_POWERPC64"
6104 "mr. %0,%1"
6105 [(set_attr "type" "compare")])
1fd4e8c1
RK
6106\f
6107;; TImode is similar, except that we usually want to compute the address into
6108;; a register and use lsi/stsi (the exception is during reload). MQ is also
ca7f5001 6109;; clobbered in stsi for POWER, so we need a SCRATCH for it.
1fd4e8c1
RK
6110(define_expand "movti"
6111 [(parallel [(set (match_operand:TI 0 "general_operand" "")
6112 (match_operand:TI 1 "general_operand" ""))
6113 (clobber (scratch:SI))])]
7e69e155 6114 "TARGET_STRING || TARGET_POWERPC64"
1fd4e8c1
RK
6115 "
6116{
6117 if (GET_CODE (operands[0]) == MEM)
6118 operands[1] = force_reg (TImode, operands[1]);
6119
6120 if (GET_CODE (operands[0]) == MEM
6121 && GET_CODE (XEXP (operands[0], 0)) != REG
6122 && ! reload_in_progress)
6123 operands[0] = change_address (operands[0], TImode,
6124 copy_addr_to_reg (XEXP (operands[0], 0)));
6125
6126 if (GET_CODE (operands[1]) == MEM
6127 && GET_CODE (XEXP (operands[1], 0)) != REG
6128 && ! reload_in_progress)
6129 operands[1] = change_address (operands[1], TImode,
6130 copy_addr_to_reg (XEXP (operands[1], 0)));
6131}")
6132
6133;; We say that MQ is clobbered in the last alternative because the first
6134;; alternative would never get used otherwise since it would need a reload
6135;; while the 2nd alternative would not. We put memory cases first so they
6136;; are preferred. Otherwise, we'd try to reload the output instead of
6137;; giving the SCRATCH mq.
6138(define_insn ""
e1469d0d 6139 [(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,m,????r,????r,????r")
1fd4e8c1
RK
6140 (match_operand:TI 1 "reg_or_mem_operand" "r,r,r,Q,m"))
6141 (clobber (match_scratch:SI 2 "=q,q#X,X,X,X"))]
7e69e155 6142 "TARGET_STRING && TARGET_POWER && ! TARGET_POWERPC64
dc4f83ca 6143 && (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))"
1fd4e8c1
RK
6144 "*
6145{
6146 switch (which_alternative)
6147 {
dc4f83ca
MM
6148 default:
6149 abort ();
6150
1fd4e8c1 6151 case 0:
ca7f5001 6152 return \"{stsi|stswi} %1,%P0,16\";
1fd4e8c1
RK
6153
6154 case 1:
ca7f5001 6155 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\;{st|stw} %Y1,%Y0\;{st|stw} %Z1,%Z0\";
1fd4e8c1
RK
6156
6157 case 2:
6158 /* Normally copy registers with lowest numbered register copied first.
6159 But copy in the other order if the first register of the output
6160 is the second, third, or fourth register in the input. */
6161 if (REGNO (operands[0]) >= REGNO (operands[1]) + 1
6162 && REGNO (operands[0]) <= REGNO (operands[1]) + 3)
deb9225a 6163 return \"mr %Z0,%Z1\;mr %Y0,%Y1\;mr %L0,%L1\;mr %0,%1\";
1fd4e8c1 6164 else
deb9225a 6165 return \"mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1\";
1fd4e8c1
RK
6166 case 3:
6167 /* If the address is not used in the output, we can use lsi. Otherwise,
6168 fall through to generating four loads. */
6169 if (! reg_overlap_mentioned_p (operands[0], operands[1]))
ca7f5001 6170 return \"{lsi|lswi} %0,%P1,16\";
1fd4e8c1
RK
6171 /* ... fall through ... */
6172 case 4:
6173 /* If the address register is the same as the register for the lowest-
6174 addressed word, load it last. Similarly for the next two words.
6175 Otherwise load lowest address to highest. */
6176 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
6177 operands[1], 0))
ca7f5001 6178 return \"{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %0,%1\";
1fd4e8c1
RK
6179 else if (refers_to_regno_p (REGNO (operands[0]) + 1,
6180 REGNO (operands[0]) + 2, operands[1], 0))
ca7f5001 6181 return \"{l|lwz} %0,%1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %L0,%L1\";
1fd4e8c1
RK
6182 else if (refers_to_regno_p (REGNO (operands[0]) + 2,
6183 REGNO (operands[0]) + 3, operands[1], 0))
ca7f5001 6184 return \"{l|lwz} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Z0,%Z1\;{l|lwz} %Y0,%Y1\";
1fd4e8c1 6185 else
ca7f5001 6186 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\";
1fd4e8c1
RK
6187 }
6188}"
b7ff3d82 6189 [(set_attr "type" "store,store,*,load,load")
b19003d8 6190 (set_attr "length" "*,16,16,*,16")])
51b8fc2c 6191
dc4f83ca
MM
6192(define_insn ""
6193 [(set (match_operand:TI 0 "reg_or_mem_operand" "=m,????r,????r")
6194 (match_operand:TI 1 "reg_or_mem_operand" "r,r,m"))
6195 (clobber (match_scratch:SI 2 "=X,X,X"))]
7e69e155 6196 "TARGET_STRING && !TARGET_POWER && ! TARGET_POWERPC64
dc4f83ca
MM
6197 && (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))"
6198 "*
6199{
6200 switch (which_alternative)
6201 {
6202 default:
6203 abort ();
6204
6205 case 0:
6206 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\;{st|stw} %Y1,%Y0\;{st|stw} %Z1,%Z0\";
6207
6208 case 1:
6209 /* Normally copy registers with lowest numbered register copied first.
6210 But copy in the other order if the first register of the output
6211 is the second, third, or fourth register in the input. */
6212 if (REGNO (operands[0]) >= REGNO (operands[1]) + 1
6213 && REGNO (operands[0]) <= REGNO (operands[1]) + 3)
6214 return \"mr %Z0,%Z1\;mr %Y0,%Y1\;mr %L0,%L1\;mr %0,%1\";
6215 else
6216 return \"mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1\";
6217 case 2:
6218 /* If the address register is the same as the register for the lowest-
6219 addressed word, load it last. Similarly for the next two words.
6220 Otherwise load lowest address to highest. */
6221 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
6222 operands[1], 0))
6223 return \"{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %0,%1\";
6224 else if (refers_to_regno_p (REGNO (operands[0]) + 1,
6225 REGNO (operands[0]) + 2, operands[1], 0))
6226 return \"{l|lwz} %0,%1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %L0,%L1\";
6227 else if (refers_to_regno_p (REGNO (operands[0]) + 2,
6228 REGNO (operands[0]) + 3, operands[1], 0))
6229 return \"{l|lwz} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Z0,%Z1\;{l|lwz} %Y0,%Y1\";
6230 else
6231 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\";
6232 }
6233}"
b7ff3d82 6234 [(set_attr "type" "store,*,load")
dc4f83ca
MM
6235 (set_attr "length" "16,16,16")])
6236
51b8fc2c
RK
6237(define_insn ""
6238 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m")
6239 (match_operand:TI 1 "input_operand" "r,m,r"))]
6240 "TARGET_POWERPC64 && (gpc_reg_operand (operands[0], TImode)
6241 || gpc_reg_operand (operands[1], TImode))"
6242 "*
6243{
6244 switch (which_alternative)
6245 {
6246 case 0:
6247 /* We normally copy the low-numbered register first. However, if
6248 the first register operand 0 is the same as the second register of
6249 operand 1, we must copy in the opposite order. */
6250 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
6251 return \"mr %L0,%L1\;mr %0,%1\";
6252 else
6253 return \"mr %0,%1\;mr %L0,%L1\";
6254 case 1:
6255 /* If the low-address word is used in the address, we must load it
6256 last. Otherwise, load it first. Note that we cannot have
6257 auto-increment in that case since the address register is known to be
6258 dead. */
6259 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
6260 operands [1], 0))
6261 return \"ld %L0,%L1\;ld %0,%1\";
6262 else
6263 return \"ld%U1 %0,%1\;ld %L0,%L1\";
6264 case 2:
6265 return \"std%U0 %1,%0\;std %L1,%L0\";
6266 }
6267}"
b7ff3d82 6268 [(set_attr "type" "*,load,store")
51b8fc2c 6269 (set_attr "length" "8,8,8")])
1fd4e8c1
RK
6270\f
6271(define_expand "load_multiple"
2f622005
RK
6272 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6273 (match_operand:SI 1 "" ""))
6274 (use (match_operand:SI 2 "" ""))])]
7e69e155 6275 "TARGET_STRING"
1fd4e8c1
RK
6276 "
6277{
6278 int regno;
6279 int count;
6280 rtx from;
6281 int i;
6282
6283 /* Support only loading a constant number of fixed-point registers from
6284 memory and only bother with this if more than two; the machine
6285 doesn't support more than eight. */
6286 if (GET_CODE (operands[2]) != CONST_INT
6287 || INTVAL (operands[2]) <= 2
6288 || INTVAL (operands[2]) > 8
6289 || GET_CODE (operands[1]) != MEM
6290 || GET_CODE (operands[0]) != REG
6291 || REGNO (operands[0]) >= 32)
6292 FAIL;
6293
6294 count = INTVAL (operands[2]);
6295 regno = REGNO (operands[0]);
6296
6297 operands[3] = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (count));
6298 from = force_reg (SImode, XEXP (operands[1], 0));
6299
6300 for (i = 0; i < count; i++)
6301 XVECEXP (operands[3], 0, i)
6302 = gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, regno + i),
538bb158
JW
6303 change_address (operands[1], SImode,
6304 plus_constant (from, i * 4)));
1fd4e8c1
RK
6305}")
6306
6307(define_insn ""
6308 [(match_parallel 0 "load_multiple_operation"
cd2b37d9 6309 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
4c99e795 6310 (mem:SI (match_operand:SI 2 "register_operand" "b")))])]
7e69e155 6311 "TARGET_STRING"
1fd4e8c1
RK
6312 "*
6313{
6314 /* We have to handle the case where the pseudo used to contain the address
e82ee4cc
RK
6315 is assigned to one of the output registers. */
6316 int i, j;
6317 int words = XVECLEN (operands[0], 0);
6318 rtx xop[10];
6319
6320 if (XVECLEN (operands[0], 0) == 1)
6321 return \"{l|lwz} %1,0(%2)\";
1fd4e8c1 6322
e82ee4cc 6323 for (i = 0; i < words; i++)
1fd4e8c1
RK
6324 if (refers_to_regno_p (REGNO (operands[1]) + i,
6325 REGNO (operands[1]) + i + 1, operands[2], 0))
6326 {
e82ee4cc
RK
6327 if (i == words-1)
6328 {
6329 xop[0] = operands[1];
6330 xop[1] = operands[2];
6331 xop[2] = GEN_INT (4 * (words-1));
d89ddcfd 6332 output_asm_insn (\"{lsi|lswi} %0,%1,%2\;{l|lwz} %1,%2(%1)\", xop);
e82ee4cc
RK
6333 return \"\";
6334 }
6335 else if (i == 0)
6336 {
6337 xop[0] = operands[1];
6338 xop[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
6339 xop[2] = GEN_INT (4 * (words-1));
6340 output_asm_insn (\"{cal %0,4(%0)|addi %0,%0,4}\;{lsi|lswi} %1,%0,%2\;{l|lwz} %0,-4(%0)\", xop);
6341 return \"\";
6342 }
6343 else
6344 {
6345 for (j = 0; j < words; j++)
6346 if (j != i)
6347 {
6348 xop[0] = gen_rtx (REG, SImode, REGNO (operands[1]) + j);
6349 xop[1] = operands[2];
6350 xop[2] = GEN_INT (j * 4);
6351 output_asm_insn (\"{l|lwz} %0,%2(%1)\", xop);
6352 }
6353 xop[0] = operands[2];
6354 xop[1] = GEN_INT (i * 4);
6355 output_asm_insn (\"{l|lwz} %0,%1(%0)\", xop);
6356 return \"\";
6357 }
1fd4e8c1
RK
6358 }
6359
e82ee4cc 6360 return \"{lsi|lswi} %1,%2,%N0\";
1fd4e8c1 6361}"
b19003d8 6362 [(set_attr "type" "load")
e82ee4cc 6363 (set_attr "length" "32")])
b19003d8 6364
b7ff3d82 6365\f
1fd4e8c1 6366(define_expand "store_multiple"
2f622005
RK
6367 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6368 (match_operand:SI 1 "" ""))
6369 (clobber (scratch:SI))
6370 (use (match_operand:SI 2 "" ""))])]
7e69e155 6371 "TARGET_STRING"
1fd4e8c1
RK
6372 "
6373{
6374 int regno;
6375 int count;
6376 rtx to;
6377 int i;
6378
6379 /* Support only storing a constant number of fixed-point registers to
6380 memory and only bother with this if more than two; the machine
6381 doesn't support more than eight. */
6382 if (GET_CODE (operands[2]) != CONST_INT
6383 || INTVAL (operands[2]) <= 2
6384 || INTVAL (operands[2]) > 8
6385 || GET_CODE (operands[0]) != MEM
6386 || GET_CODE (operands[1]) != REG
6387 || REGNO (operands[1]) >= 32)
6388 FAIL;
6389
6390 count = INTVAL (operands[2]);
6391 regno = REGNO (operands[1]);
6392
6393 operands[3] = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (count + 1));
6394 to = force_reg (SImode, XEXP (operands[0], 0));
6395
6396 XVECEXP (operands[3], 0, 0)
538bb158
JW
6397 = gen_rtx (SET, VOIDmode, change_address (operands[0], SImode, to),
6398 operands[1]);
1fd4e8c1
RK
6399 XVECEXP (operands[3], 0, 1) = gen_rtx (CLOBBER, VOIDmode,
6400 gen_rtx (SCRATCH, SImode));
6401
6402 for (i = 1; i < count; i++)
6403 XVECEXP (operands[3], 0, i + 1)
6404 = gen_rtx (SET, VOIDmode,
538bb158
JW
6405 change_address (operands[0], SImode,
6406 plus_constant (to, i * 4)),
1fd4e8c1
RK
6407 gen_rtx (REG, SImode, regno + i));
6408}")
6409
6410(define_insn ""
6411 [(match_parallel 0 "store_multiple_operation"
6412 [(set (match_operand:SI 1 "indirect_operand" "=Q")
cd2b37d9 6413 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 6414 (clobber (match_scratch:SI 3 "=q"))])]
7e69e155 6415 "TARGET_STRING && TARGET_POWER"
b7ff3d82
DE
6416 "{stsi|stswi} %2,%P1,%O0"
6417 [(set_attr "type" "store")])
d14a6d05
MM
6418
6419(define_insn ""
6420 [(match_parallel 0 "store_multiple_operation"
4c99e795 6421 [(set (mem:SI (match_operand:SI 1 "register_operand" "b"))
d14a6d05
MM
6422 (match_operand:SI 2 "gpc_reg_operand" "r"))
6423 (clobber (match_scratch:SI 3 "X"))])]
7e69e155 6424 "TARGET_STRING && !TARGET_POWER"
b7ff3d82
DE
6425 "{stsi|stswi} %2,%1,%O0"
6426 [(set_attr "type" "store")])
7e69e155
MM
6427
6428\f
6429;; String/block move insn.
6430;; Argument 0 is the destination
6431;; Argument 1 is the source
6432;; Argument 2 is the length
6433;; Argument 3 is the alignment
6434
6435(define_expand "movstrsi"
b6c9286a
MM
6436 [(parallel [(set (match_operand:BLK 0 "" "")
6437 (match_operand:BLK 1 "" ""))
6438 (use (match_operand:SI 2 "" ""))
6439 (use (match_operand:SI 3 "" ""))])]
7e69e155
MM
6440 ""
6441 "
6442{
6443 if (expand_block_move (operands))
6444 DONE;
6445 else
6446 FAIL;
6447}")
6448
6449;; Move up to 32 bytes at a time. The fixed registers are needed because the
6450;; register allocator doesn't have a clue about allocating 8 word registers
6451(define_expand "movstrsi_8reg"
b6c9286a
MM
6452 [(parallel [(set (match_operand 0 "" "")
6453 (match_operand 1 "" ""))
6454 (use (match_operand 2 "" ""))
6455 (use (match_operand 3 "" ""))
7e69e155
MM
6456 (clobber (reg:SI 5))
6457 (clobber (reg:SI 6))
6458 (clobber (reg:SI 7))
6459 (clobber (reg:SI 8))
6460 (clobber (reg:SI 9))
6461 (clobber (reg:SI 10))
6462 (clobber (reg:SI 11))
6463 (clobber (reg:SI 12))
3c67b673 6464 (clobber (match_scratch:SI 4 ""))])]
7e69e155
MM
6465 "TARGET_STRING"
6466 "")
6467
6468(define_insn ""
3c67b673
RK
6469 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6470 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6471 (use (match_operand:SI 2 "immediate_operand" "i"))
6472 (use (match_operand:SI 3 "immediate_operand" "i"))
6473 (clobber (match_operand:SI 4 "register_operand" "=r"))
7e69e155
MM
6474 (clobber (reg:SI 6))
6475 (clobber (reg:SI 7))
6476 (clobber (reg:SI 8))
6477 (clobber (reg:SI 9))
6478 (clobber (reg:SI 10))
6479 (clobber (reg:SI 11))
6480 (clobber (reg:SI 12))
3c67b673 6481 (clobber (match_scratch:SI 5 "=q"))]
7e69e155
MM
6482 "TARGET_STRING && TARGET_POWER
6483 && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32) || INTVAL (operands[2]) == 0)
6484 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
6485 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
3c67b673
RK
6486 && REGNO (operands[4]) == 5"
6487 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
b7ff3d82
DE
6488 [(set_attr "type" "load")
6489 (set_attr "length" "8")])
7e69e155
MM
6490
6491(define_insn ""
3c67b673
RK
6492 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6493 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6494 (use (match_operand:SI 2 "immediate_operand" "i"))
6495 (use (match_operand:SI 3 "immediate_operand" "i"))
6496 (clobber (match_operand:SI 4 "register_operand" "=r"))
7e69e155
MM
6497 (clobber (reg:SI 6))
6498 (clobber (reg:SI 7))
6499 (clobber (reg:SI 8))
6500 (clobber (reg:SI 9))
6501 (clobber (reg:SI 10))
6502 (clobber (reg:SI 11))
6503 (clobber (reg:SI 12))
3c67b673 6504 (clobber (match_scratch:SI 5 "X"))]
7e69e155
MM
6505 "TARGET_STRING && !TARGET_POWER
6506 && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32) || INTVAL (operands[2]) == 0)
6507 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
6508 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
3c67b673
RK
6509 && REGNO (operands[4]) == 5"
6510 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
b7ff3d82
DE
6511 [(set_attr "type" "load")
6512 (set_attr "length" "8")])
7e69e155
MM
6513
6514;; Move up to 24 bytes at a time. The fixed registers are needed because the
6515;; register allocator doesn't have a clue about allocating 6 word registers
6516(define_expand "movstrsi_6reg"
b6c9286a
MM
6517 [(parallel [(set (match_operand 0 "" "")
6518 (match_operand 1 "" ""))
6519 (use (match_operand 2 "" ""))
6520 (use (match_operand 3 "" ""))
7e69e155
MM
6521 (clobber (reg:SI 7))
6522 (clobber (reg:SI 8))
6523 (clobber (reg:SI 9))
6524 (clobber (reg:SI 10))
6525 (clobber (reg:SI 11))
6526 (clobber (reg:SI 12))
3c67b673 6527 (clobber (match_scratch:SI 4 ""))])]
7e69e155
MM
6528 "TARGET_STRING"
6529 "")
6530
6531(define_insn ""
3c67b673
RK
6532 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6533 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6534 (use (match_operand:SI 2 "immediate_operand" "i"))
6535 (use (match_operand:SI 3 "immediate_operand" "i"))
6536 (clobber (match_operand:SI 4 "register_operand" "=r"))
7e69e155
MM
6537 (clobber (reg:SI 8))
6538 (clobber (reg:SI 9))
6539 (clobber (reg:SI 10))
6540 (clobber (reg:SI 11))
6541 (clobber (reg:SI 12))
3c67b673 6542 (clobber (match_scratch:SI 5 "=q"))]
7e69e155
MM
6543 "TARGET_STRING && TARGET_POWER
6544 && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24
6545 && (REGNO (operands[0]) < 7 || REGNO (operands[0]) > 12)
6546 && (REGNO (operands[1]) < 7 || REGNO (operands[1]) > 12)
3c67b673
RK
6547 && REGNO (operands[4]) == 7"
6548 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
b7ff3d82
DE
6549 [(set_attr "type" "load")
6550 (set_attr "length" "8")])
7e69e155
MM
6551
6552(define_insn ""
3c67b673
RK
6553 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6554 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6555 (use (match_operand:SI 2 "immediate_operand" "i"))
6556 (use (match_operand:SI 3 "immediate_operand" "i"))
6557 (clobber (match_operand:SI 4 "register_operand" "=r"))
7e69e155
MM
6558 (clobber (reg:SI 8))
6559 (clobber (reg:SI 9))
6560 (clobber (reg:SI 10))
6561 (clobber (reg:SI 11))
6562 (clobber (reg:SI 12))
3c67b673 6563 (clobber (match_scratch:SI 5 "X"))]
7e69e155
MM
6564 "TARGET_STRING && !TARGET_POWER
6565 && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
6566 && (REGNO (operands[0]) < 7 || REGNO (operands[0]) > 12)
6567 && (REGNO (operands[1]) < 7 || REGNO (operands[1]) > 12)
3c67b673
RK
6568 && REGNO (operands[4]) == 7"
6569 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
b7ff3d82
DE
6570 [(set_attr "type" "load")
6571 (set_attr "length" "8")])
7e69e155
MM
6572
6573;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill problems
6574;; with TImode
6575(define_expand "movstrsi_4reg"
b6c9286a
MM
6576 [(parallel [(set (match_operand 0 "" "")
6577 (match_operand 1 "" ""))
6578 (use (match_operand 2 "" ""))
6579 (use (match_operand 3 "" ""))
7e69e155
MM
6580 (clobber (reg:SI 9))
6581 (clobber (reg:SI 10))
6582 (clobber (reg:SI 11))
6583 (clobber (reg:SI 12))
3c67b673 6584 (clobber (match_scratch:SI 4 ""))])]
7e69e155
MM
6585 "TARGET_STRING"
6586 "")
6587
6588(define_insn ""
3c67b673
RK
6589 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6590 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6591 (use (match_operand:SI 2 "immediate_operand" "i"))
6592 (use (match_operand:SI 3 "immediate_operand" "i"))
6593 (clobber (match_operand:SI 4 "register_operand" "=r"))
7e69e155
MM
6594 (clobber (reg:SI 10))
6595 (clobber (reg:SI 11))
6596 (clobber (reg:SI 12))
3c67b673 6597 (clobber (match_scratch:SI 5 "=q"))]
7e69e155
MM
6598 "TARGET_STRING && TARGET_POWER
6599 && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
6600 && (REGNO (operands[0]) < 9 || REGNO (operands[0]) > 12)
6601 && (REGNO (operands[1]) < 9 || REGNO (operands[1]) > 12)
3c67b673
RK
6602 && REGNO (operands[4]) == 9"
6603 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
b7ff3d82
DE
6604 [(set_attr "type" "load")
6605 (set_attr "length" "8")])
7e69e155
MM
6606
6607(define_insn ""
3c67b673
RK
6608 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6609 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6610 (use (match_operand:SI 2 "immediate_operand" "i"))
6611 (use (match_operand:SI 3 "immediate_operand" "i"))
6612 (clobber (match_operand:SI 4 "register_operand" "=r"))
7e69e155
MM
6613 (clobber (reg:SI 10))
6614 (clobber (reg:SI 11))
6615 (clobber (reg:SI 12))
3c67b673 6616 (clobber (match_scratch:SI 5 "X"))]
7e69e155
MM
6617 "TARGET_STRING && !TARGET_POWER
6618 && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
6619 && (REGNO (operands[0]) < 9 || REGNO (operands[0]) > 12)
6620 && (REGNO (operands[1]) < 9 || REGNO (operands[1]) > 12)
3c67b673
RK
6621 && REGNO (operands[4]) == 9"
6622 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
b7ff3d82
DE
6623 [(set_attr "type" "load")
6624 (set_attr "length" "8")])
7e69e155
MM
6625
6626;; Move up to 8 bytes at a time.
6627(define_expand "movstrsi_2reg"
b6c9286a
MM
6628 [(parallel [(set (match_operand 0 "" "")
6629 (match_operand 1 "" ""))
6630 (use (match_operand 2 "" ""))
6631 (use (match_operand 3 "" ""))
3c67b673
RK
6632 (clobber (match_scratch:DI 4 ""))
6633 (clobber (match_scratch:SI 5 ""))])]
7e69e155
MM
6634 "TARGET_STRING && !TARGET_64BIT"
6635 "")
6636
6637(define_insn ""
3c67b673
RK
6638 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6639 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6640 (use (match_operand:SI 2 "immediate_operand" "i"))
6641 (use (match_operand:SI 3 "immediate_operand" "i"))
6642 (clobber (match_scratch:DI 4 "=&r"))
6643 (clobber (match_scratch:SI 5 "=q"))]
7e69e155 6644 "TARGET_STRING && TARGET_POWER && !TARGET_64BIT
3c67b673
RK
6645 && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
6646 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
b7ff3d82
DE
6647 [(set_attr "type" "load")
6648 (set_attr "length" "8")])
7e69e155
MM
6649
6650(define_insn ""
3c67b673
RK
6651 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6652 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6653 (use (match_operand:SI 2 "immediate_operand" "i"))
6654 (use (match_operand:SI 3 "immediate_operand" "i"))
6655 (clobber (match_scratch:DI 4 "=&r"))
6656 (clobber (match_scratch:SI 5 "X"))]
7e69e155
MM
6657 "TARGET_STRING && !TARGET_POWER && !TARGET_64BIT
6658 && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
3c67b673 6659 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
b7ff3d82
DE
6660 [(set_attr "type" "load")
6661 (set_attr "length" "8")])
7e69e155
MM
6662
6663;; Move up to 4 bytes at a time.
6664(define_expand "movstrsi_1reg"
b6c9286a
MM
6665 [(parallel [(set (match_operand 0 "" "")
6666 (match_operand 1 "" ""))
6667 (use (match_operand 2 "" ""))
6668 (use (match_operand 3 "" ""))
3c67b673
RK
6669 (clobber (match_scratch:SI 4 ""))
6670 (clobber (match_scratch:SI 5 ""))])]
7e69e155
MM
6671 "TARGET_STRING"
6672 "")
6673
6674(define_insn ""
3c67b673
RK
6675 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6676 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6677 (use (match_operand:SI 2 "immediate_operand" "i"))
6678 (use (match_operand:SI 3 "immediate_operand" "i"))
6679 (clobber (match_scratch:SI 4 "=&r"))
6680 (clobber (match_scratch:SI 5 "=q"))]
7e69e155
MM
6681 "TARGET_STRING && TARGET_POWER
6682 && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
3c67b673 6683 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
b7ff3d82
DE
6684 [(set_attr "type" "load")
6685 (set_attr "length" "8")])
7e69e155
MM
6686
6687(define_insn ""
3c67b673
RK
6688 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6689 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6690 (use (match_operand:SI 2 "immediate_operand" "i"))
6691 (use (match_operand:SI 3 "immediate_operand" "i"))
6692 (clobber (match_scratch:SI 4 "=&r"))
6693 (clobber (match_scratch:SI 5 "X"))]
7e69e155
MM
6694 "TARGET_STRING && !TARGET_POWER
6695 && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
3c67b673 6696 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
b7ff3d82
DE
6697 [(set_attr "type" "load")
6698 (set_attr "length" "8")])
7e69e155 6699
1fd4e8c1 6700\f
7e69e155 6701;; Define insns that do load or store with update. Some of these we can
1fd4e8c1
RK
6702;; get by using pre-decrement or pre-increment, but the hardware can also
6703;; do cases where the increment is not the size of the object.
6704;;
6705;; In all these cases, we use operands 0 and 1 for the register being
6706;; incremented because those are the operands that local-alloc will
6707;; tie and these are the pair most likely to be tieable (and the ones
6708;; that will benefit the most).
6709
51b8fc2c
RK
6710(define_insn ""
6711 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
ad8bd902 6712 (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
51b8fc2c
RK
6713 (match_operand:DI 2 "reg_or_short_operand" "r,I"))))
6714 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
6715 (plus:DI (match_dup 1) (match_dup 2)))]
6716 "TARGET_POWERPC64"
6717 "@
6718 ldux %3,%0,%2
6719 ldu %3,%2(%0)"
6720 [(set_attr "type" "load")])
6721
287f13ff
RK
6722(define_insn ""
6723 [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
6724 (sign_extend:DI
6725 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
6726 (match_operand:DI 2 "gpc_reg_operand" "r")))))
6727 (set (match_operand:DI 0 "gpc_reg_operand" "=b")
6728 (plus:DI (match_dup 1) (match_dup 2)))]
6729 "TARGET_POWERPC64"
6730 "lwaux %3,%0,%2"
6731 [(set_attr "type" "load")])
6732
4697a36c 6733(define_insn "movdi_update"
51b8fc2c
RK
6734 [(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
6735 (match_operand:DI 2 "reg_or_short_operand" "r,I")))
6736 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
6737 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
6738 (plus:DI (match_dup 1) (match_dup 2)))]
6739 "TARGET_POWERPC64"
6740 "@
6741 stdux %3,%0,%2
b7ff3d82
DE
6742 stdu %3,%2(%0)"
6743 [(set_attr "type" "store")])
51b8fc2c 6744
1fd4e8c1 6745(define_insn ""
cd2b37d9
RK
6746 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
6747 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6748 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
cd2b37d9 6749 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
6750 (plus:SI (match_dup 1) (match_dup 2)))]
6751 ""
6752 "@
ca7f5001
RK
6753 {lux|lwzux} %3,%0,%2
6754 {lu|lwzu} %3,%2(%0)"
cfb557c4 6755 [(set_attr "type" "load")])
1fd4e8c1 6756
4697a36c 6757(define_insn "movsi_update"
cd2b37d9 6758 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6759 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
cd2b37d9
RK
6760 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
6761 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
6762 (plus:SI (match_dup 1) (match_dup 2)))]
6763 ""
6764 "@
ca7f5001 6765 {stux|stwux} %3,%0,%2
b7ff3d82
DE
6766 {stu|stwu} %3,%2(%0)"
6767 [(set_attr "type" "store")])
1fd4e8c1
RK
6768
6769(define_insn ""
cd2b37d9
RK
6770 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
6771 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6772 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
cd2b37d9 6773 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
6774 (plus:SI (match_dup 1) (match_dup 2)))]
6775 ""
6776 "@
5f243543
RK
6777 lhzux %3,%0,%2
6778 lhzu %3,%2(%0)"
cfb557c4 6779 [(set_attr "type" "load")])
1fd4e8c1
RK
6780
6781(define_insn ""
cd2b37d9 6782 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
1fd4e8c1 6783 (zero_extend:SI
cd2b37d9 6784 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6785 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
cd2b37d9 6786 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
6787 (plus:SI (match_dup 1) (match_dup 2)))]
6788 ""
6789 "@
5f243543
RK
6790 lhzux %3,%0,%2
6791 lhzu %3,%2(%0)"
cfb557c4 6792 [(set_attr "type" "load")])
1fd4e8c1
RK
6793
6794(define_insn ""
cd2b37d9 6795 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
1fd4e8c1 6796 (sign_extend:SI
cd2b37d9 6797 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6798 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
cd2b37d9 6799 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
6800 (plus:SI (match_dup 1) (match_dup 2)))]
6801 ""
6802 "@
5f243543
RK
6803 lhaux %3,%0,%2
6804 lhau %3,%2(%0)"
cfb557c4 6805 [(set_attr "type" "load")])
1fd4e8c1
RK
6806
6807(define_insn ""
cd2b37d9 6808 [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6809 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
cd2b37d9
RK
6810 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
6811 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
6812 (plus:SI (match_dup 1) (match_dup 2)))]
6813 ""
6814 "@
5f243543 6815 sthux %3,%0,%2
b7ff3d82
DE
6816 sthu %3,%2(%0)"
6817 [(set_attr "type" "store")])
1fd4e8c1
RK
6818
6819(define_insn ""
cd2b37d9
RK
6820 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
6821 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6822 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
cd2b37d9 6823 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
6824 (plus:SI (match_dup 1) (match_dup 2)))]
6825 ""
6826 "@
5f243543
RK
6827 lbzux %3,%0,%2
6828 lbzu %3,%2(%0)"
cfb557c4 6829 [(set_attr "type" "load")])
1fd4e8c1
RK
6830
6831(define_insn ""
cd2b37d9 6832 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
1fd4e8c1 6833 (zero_extend:SI
cd2b37d9 6834 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6835 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
cd2b37d9 6836 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
6837 (plus:SI (match_dup 1) (match_dup 2)))]
6838 ""
6839 "@
5f243543
RK
6840 lbzux %3,%0,%2
6841 lbzu %3,%2(%0)"
cfb557c4 6842 [(set_attr "type" "load")])
1fd4e8c1
RK
6843
6844(define_insn ""
cd2b37d9 6845 [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6846 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
cd2b37d9
RK
6847 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
6848 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
6849 (plus:SI (match_dup 1) (match_dup 2)))]
6850 ""
6851 "@
5f243543 6852 stbux %3,%0,%2
b7ff3d82
DE
6853 stbu %3,%2(%0)"
6854 [(set_attr "type" "store")])
1fd4e8c1
RK
6855
6856(define_insn ""
cd2b37d9 6857 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
df8b713c 6858 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6859 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
cd2b37d9 6860 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1 6861 (plus:SI (match_dup 1) (match_dup 2)))]
d14a6d05 6862 "TARGET_HARD_FLOAT"
1fd4e8c1 6863 "@
5f243543
RK
6864 lfsux %3,%0,%2
6865 lfsu %3,%2(%0)"
cfb557c4 6866 [(set_attr "type" "fpload")])
1fd4e8c1
RK
6867
6868(define_insn ""
cd2b37d9 6869 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6870 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
cd2b37d9
RK
6871 (match_operand:SF 3 "gpc_reg_operand" "f,f"))
6872 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1 6873 (plus:SI (match_dup 1) (match_dup 2)))]
d14a6d05 6874 "TARGET_HARD_FLOAT"
1fd4e8c1 6875 "@
85fff2f3 6876 stfsux %3,%0,%2
b7ff3d82
DE
6877 stfsu %3,%2(%0)"
6878 [(set_attr "type" "fpstore")])
1fd4e8c1
RK
6879
6880(define_insn ""
cd2b37d9
RK
6881 [(set (match_operand:DF 3 "gpc_reg_operand" "=f,f")
6882 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6883 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
cd2b37d9 6884 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1 6885 (plus:SI (match_dup 1) (match_dup 2)))]
d14a6d05 6886 "TARGET_HARD_FLOAT"
1fd4e8c1 6887 "@
5f243543
RK
6888 lfdux %3,%0,%2
6889 lfdu %3,%2(%0)"
cfb557c4 6890 [(set_attr "type" "fpload")])
1fd4e8c1
RK
6891
6892(define_insn ""
cd2b37d9 6893 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6894 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
cd2b37d9
RK
6895 (match_operand:DF 3 "gpc_reg_operand" "f,f"))
6896 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1 6897 (plus:SI (match_dup 1) (match_dup 2)))]
d14a6d05 6898 "TARGET_HARD_FLOAT"
1fd4e8c1 6899 "@
5f243543 6900 stfdux %3,%0,%2
b7ff3d82
DE
6901 stfdu %3,%2(%0)"
6902 [(set_attr "type" "fpstore")])
4c70a4f3
RK
6903
6904;; Peephole to convert two consecutive FP loads or stores into lfq/stfq.
6905
6906(define_peephole
6907 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
6908 (match_operand:DF 1 "memory_operand" ""))
6909 (set (match_operand:DF 2 "gpc_reg_operand" "=f")
6910 (match_operand:DF 3 "memory_operand" ""))]
6911 "TARGET_POWER2
d14a6d05 6912 && TARGET_HARD_FLOAT
4c70a4f3
RK
6913 && registers_ok_for_quad_peep (operands[0], operands[2])
6914 && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
6915 && addrs_ok_for_quad_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
6916 "lfq%U1%X1 %0,%1")
6917
6918(define_peephole
6919 [(set (match_operand:DF 0 "memory_operand" "")
6920 (match_operand:DF 1 "gpc_reg_operand" "f"))
6921 (set (match_operand:DF 2 "memory_operand" "")
6922 (match_operand:DF 3 "gpc_reg_operand" "f"))]
6923 "TARGET_POWER2
d14a6d05 6924 && TARGET_HARD_FLOAT
4c70a4f3
RK
6925 && registers_ok_for_quad_peep (operands[1], operands[3])
6926 && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
6927 && addrs_ok_for_quad_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
6928 "stfq%U0%X0 %1,%0")
1fd4e8c1
RK
6929\f
6930;; Next come insns related to the calling sequence.
6931;;
6932;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
7e69e155 6933;; We move the back-chain and decrement the stack pointer.
1fd4e8c1
RK
6934
6935(define_expand "allocate_stack"
6936 [(set (reg:SI 1)
01def764 6937 (minus:SI (reg:SI 1) (match_operand:SI 0 "reg_or_short_operand" "")))]
1fd4e8c1
RK
6938 ""
6939 "
4697a36c 6940{ rtx chain = gen_reg_rtx (Pmode);
1fd4e8c1 6941 rtx stack_bot = gen_rtx (MEM, Pmode, stack_pointer_rtx);
4697a36c 6942 rtx neg_op0;
1fd4e8c1
RK
6943
6944 emit_move_insn (chain, stack_bot);
4697a36c 6945
979721f8
MM
6946 /* Under Windows NT, we need to add stack probes for large/variable allocations,
6947 so do it via a call to the external function alloca, instead of doing it
6948 inline. */
6949 if (DEFAULT_ABI == ABI_NT
6950 && (GET_CODE (operands[0]) != CONST_INT || INTVAL (operands[0]) > 4096))
6951 {
cea05fab
MM
6952 rtx tmp = gen_reg_rtx (SImode);
6953 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"__allocate_stack\"),
6954 tmp, 0, SImode, 1, operands[0], Pmode);
6955 emit_insn (gen_set_sp (tmp));
979721f8
MM
6956 DONE;
6957 }
6958
4697a36c
MM
6959 if (GET_CODE (operands[0]) != CONST_INT
6960 || INTVAL (operands[0]) < -32767
6961 || INTVAL (operands[0]) > 32768)
6962 {
6963 neg_op0 = gen_reg_rtx (Pmode);
e6ca2c17 6964 if (TARGET_32BIT)
4697a36c 6965 emit_insn (gen_negsi2 (neg_op0, operands[0]));
e6ca2c17
DE
6966 else
6967 emit_insn (gen_negdi2 (neg_op0, operands[0]));
4697a36c
MM
6968 }
6969 else
6970 neg_op0 = GEN_INT (- INTVAL (operands[0]));
6971
e6ca2c17 6972 if (TARGET_32BIT)
4697a36c 6973 emit_insn (gen_movsi_update (stack_pointer_rtx, stack_pointer_rtx, neg_op0, chain));
e6ca2c17
DE
6974 else
6975 emit_insn (gen_movdi_update (stack_pointer_rtx, stack_pointer_rtx, neg_op0, chain));
4697a36c 6976
1fd4e8c1
RK
6977 DONE;
6978}")
59257ff7 6979
cea05fab
MM
6980;; Marker to indicate that the stack pointer was changed under NT in
6981;; ways not known to the compiler
6982
6983(define_insn "set_sp"
6984 [(set (reg:SI 1)
6985 (unspec [(match_operand:SI 0 "register_operand" "r")] 7))]
6986 ""
6987 ""
6988 [(set_attr "length" "0")])
6989
59257ff7
RK
6990;; These patterns say how to save and restore the stack pointer. We need not
6991;; save the stack pointer at function level since we are careful to
6992;; preserve the backchain. At block level, we have to restore the backchain
6993;; when we restore the stack pointer.
6994;;
6995;; For nonlocal gotos, we must save both the stack pointer and its
6996;; backchain and restore both. Note that in the nonlocal case, the
6997;; save area is a memory location.
6998
6999(define_expand "save_stack_function"
7000 [(use (const_int 0))]
7001 ""
7002 "")
7003
7004(define_expand "restore_stack_function"
7005 [(use (const_int 0))]
7006 ""
7007 "")
7008
7009(define_expand "restore_stack_block"
7010 [(set (match_dup 2) (mem:SI (match_operand:SI 0 "register_operand" "")))
7011 (set (match_dup 0) (match_operand:SI 1 "register_operand" ""))
7012 (set (mem:SI (match_dup 0)) (match_dup 2))]
7013 ""
7014 "
7015{ operands[2] = gen_reg_rtx (SImode); }")
7016
7017(define_expand "save_stack_nonlocal"
7018 [(match_operand:DI 0 "memory_operand" "")
7019 (match_operand:SI 1 "register_operand" "")]
7020 ""
7021 "
7022{
7023 rtx temp = gen_reg_rtx (SImode);
7024
7025 /* Copy the backchain to the first word, sp to the second. */
7026 emit_move_insn (temp, gen_rtx (MEM, SImode, operands[1]));
7027 emit_move_insn (operand_subword (operands[0], 0, 0, DImode), temp);
7028 emit_move_insn (operand_subword (operands[0], 1, 0, DImode), operands[1]);
7029 DONE;
7030}")
7e69e155 7031
59257ff7
RK
7032(define_expand "restore_stack_nonlocal"
7033 [(match_operand:SI 0 "register_operand" "")
7034 (match_operand:DI 1 "memory_operand" "")]
7035 ""
7036 "
7037{
7038 rtx temp = gen_reg_rtx (SImode);
7039
7040 /* Restore the backchain from the first word, sp from the second. */
7041 emit_move_insn (temp, operand_subword (operands[1], 0, 0, DImode));
7042 emit_move_insn (operands[0], operand_subword (operands[1], 1, 0, DImode));
7043 emit_move_insn (gen_rtx (MEM, SImode, operands[0]), temp);
7044 DONE;
7045}")
b6c9286a 7046
b7ff3d82 7047\f
b6c9286a
MM
7048;; A function pointer under AIX is a pointer to a data area whose first word
7049;; contains the actual address of the function, whose second word contains a
7050;; pointer to its TOC, and whose third word contains a value to place in the
7051;; static chain register (r11). Note that if we load the static chain, our
1fd4e8c1
RK
7052;; "trampoline" need not have any executable code.
7053;;
b6c9286a
MM
7054;; operands[0] is a register pointing to the 3 word descriptor (aka, the function address)
7055;; operands[1] is the stack size to clean up
7056;; operands[2] is the value FUNCTION_ARG returns for the VOID argument (must be 0 for AIX)
7057;; operands[3] is location to store the TOC
7058;; operands[4] is the TOC register
7059;; operands[5] is the static chain register
7060;;
7061;; We do not break this into separate insns, so that the scheduler will not try
7062;; to move the load of the new TOC before any loads from the TOC.
7063
7064(define_insn "call_indirect_aix"
7065 [(call (mem:SI (match_operand:SI 0 "register_operand" "b"))
7066 (match_operand 1 "const_int_operand" "n"))
6a4cee5f 7067 (use (match_operand 2 "const_int_operand" "n"))
b6c9286a
MM
7068 (use (match_operand 3 "offsettable_addr_operand" "p"))
7069 (use (match_operand 4 "register_operand" "r"))
7070 (clobber (match_operand 5 "register_operand" "=r"))
7071 (clobber (match_scratch:SI 6 "=&r"))
7072 (clobber (match_scratch:SI 7 "=l"))]
6a4cee5f
MM
7073 "DEFAULT_ABI == ABI_AIX
7074 && (INTVAL (operands[2]) == CALL_NORMAL || (INTVAL (operands[2]) & CALL_LONG) != 0)"
7075 "{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
7076 [(set_attr "type" "load")
7077 (set_attr "length" "28")])
b6c9286a
MM
7078
7079(define_insn "call_value_indirect_aix"
7080 [(set (match_operand 0 "register_operand" "fg")
7081 (call (mem:SI (match_operand:SI 1 "register_operand" "b"))
7082 (match_operand 2 "const_int_operand" "n")))
6a4cee5f 7083 (use (match_operand 3 "const_int_operand" "n"))
b6c9286a
MM
7084 (use (match_operand 4 "offsettable_addr_operand" "p"))
7085 (use (match_operand 5 "register_operand" "r"))
7086 (clobber (match_operand 6 "register_operand" "=r"))
7087 (clobber (match_scratch:SI 7 "=&r"))
7088 (clobber (match_scratch:SI 8 "=l"))]
6a4cee5f
MM
7089 "DEFAULT_ABI == ABI_AIX
7090 && (INTVAL (operands[3]) == CALL_NORMAL || (INTVAL (operands[3]) & CALL_LONG) != 0)"
b6c9286a 7091 "{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"
b7ff3d82
DE
7092 [(set_attr "type" "load")
7093 (set_attr "length" "28")])
b6c9286a
MM
7094
7095;; A function pointer undef NT is a pointer to a data area whose first word
7096;; contains the actual address of the function, whose second word contains a
7097;; pointer to its TOC. The static chain is not stored under NT, which means
7098;; that we need a trampoline.
7099;;
7100;; operands[0] is an SImode pseudo in which we place the address of the function.
7101;; operands[1] is the stack size to clean up
7102;; operands[2] is the value FUNCTION_ARG returns for the VOID argument (must be 0 for NT)
7103;; operands[3] is location to store the TOC
7104;; operands[4] is the TOC register
7105;;
7106;; We do not break this into separate insns, so that the scheduler will not try
7107;; to move the load of the new TOC before any loads from the TOC.
7108
7109(define_insn "call_indirect_nt"
7110 [(call (mem:SI (match_operand:SI 0 "register_operand" "b"))
7111 (match_operand 1 "const_int_operand" "n"))
6a4cee5f 7112 (use (match_operand 2 "const_int_operand" "n"))
b6c9286a
MM
7113 (use (match_operand 3 "offsettable_addr_operand" "p"))
7114 (use (match_operand 4 "register_operand" "r"))
7115 (clobber (match_scratch:SI 5 "=&r"))
7116 (clobber (match_scratch:SI 6 "=l"))]
6a4cee5f
MM
7117 "DEFAULT_ABI == ABI_NT
7118 && (INTVAL (operands[2]) == CALL_NORMAL || (INTVAL (operands[2]) & CALL_LONG) != 0)"
e1f83b4d 7119 "{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
7120 [(set_attr "type" "load")
7121 (set_attr "length" "24")])
b6c9286a
MM
7122
7123(define_insn "call_value_indirect_nt"
7124 [(set (match_operand 0 "register_operand" "fg")
7125 (call (mem:SI (match_operand:SI 1 "register_operand" "b"))
7126 (match_operand 2 "const_int_operand" "n")))
6a4cee5f 7127 (use (match_operand 3 "const_int_operand" "n"))
b6c9286a
MM
7128 (use (match_operand 4 "offsettable_addr_operand" "p"))
7129 (use (match_operand 5 "register_operand" "r"))
7130 (clobber (match_scratch:SI 6 "=&r"))
7131 (clobber (match_scratch:SI 7 "=l"))]
6a4cee5f
MM
7132 "DEFAULT_ABI == ABI_NT
7133 && (INTVAL (operands[3]) == CALL_NORMAL || (INTVAL (operands[3]) & CALL_LONG) != 0)"
e1f83b4d 7134 "{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
7135 [(set_attr "type" "load")
7136 (set_attr "length" "24")])
b6c9286a
MM
7137
7138;; A function pointer under System V is just a normal pointer
7139;; operands[0] is the function pointer
7140;; operands[1] is the stack size to clean up
7141;; operands[2] is the value FUNCTION_ARG returns for the VOID argument which indicates how to set cr1
7142
7143(define_insn "call_indirect_sysv"
7144 [(call (mem:SI (match_operand:SI 0 "register_operand" "l,l"))
7145 (match_operand 1 "const_int_operand" "n,n"))
7146 (use (match_operand 2 "const_int_operand" "O,n"))
7147 (clobber (match_scratch:SI 3 "=l,l"))]
c81bebd7 7148 "DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS || DEFAULT_ABI == ABI_AIX_NODESC"
b6c9286a
MM
7149 "*
7150{
6a4cee5f
MM
7151 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
7152 output_asm_insn (\"crxor 6,6,6\", operands);
1fd4e8c1 7153
6a4cee5f
MM
7154 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
7155 output_asm_insn (\"creqv 6,6,6\", operands);
b6c9286a
MM
7156
7157 return \"{brl|blrl}\";
7158}"
b7ff3d82
DE
7159 [(set_attr "type" "jmpreg")
7160 (set_attr "length" "4,8")])
b6c9286a
MM
7161
7162(define_insn "call_value_indirect_sysv"
7163 [(set (match_operand 0 "register_operand" "=fg,fg")
7164 (call (mem:SI (match_operand:SI 1 "register_operand" "l,l"))
7165 (match_operand 2 "const_int_operand" "n,n")))
7166 (use (match_operand 3 "const_int_operand" "O,n"))
7167 (clobber (match_scratch:SI 4 "=l,l"))]
c81bebd7 7168 "DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS || DEFAULT_ABI == ABI_AIX_NODESC"
b6c9286a
MM
7169 "*
7170{
6a4cee5f
MM
7171 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
7172 output_asm_insn (\"crxor 6,6,6\", operands);
b6c9286a 7173
6a4cee5f
MM
7174 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
7175 output_asm_insn (\"creqv 6,6,6\", operands);
b6c9286a
MM
7176
7177 return \"{brl|blrl}\";
7178}"
b7ff3d82
DE
7179 [(set_attr "type" "jmpreg")
7180 (set_attr "length" "4,8")])
1fd4e8c1 7181
b6c9286a 7182;; Now the definitions for the call and call_value insns
1fd4e8c1
RK
7183(define_expand "call"
7184 [(parallel [(call (mem:SI (match_operand:SI 0 "address_operand" ""))
7185 (match_operand 1 "" ""))
4697a36c 7186 (use (match_operand 2 "" ""))
1fd4e8c1
RK
7187 (clobber (scratch:SI))])]
7188 ""
7189 "
7190{
7191 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != CONST_INT)
7192 abort ();
7193
7194 operands[0] = XEXP (operands[0], 0);
7509c759
MM
7195
7196 /* Convert NT DLL imports into an indirect call. */
7197 if (GET_CODE (operands[0]) == SYMBOL_REF
6a4cee5f 7198 && (INTVAL (operands[2]) & CALL_NT_DLLIMPORT) != 0)
7509c759
MM
7199 {
7200 operands[0] = rs6000_dll_import_ref (operands[0]);
7201 operands[2] = GEN_INT ((int)CALL_NORMAL);
7202 }
7203
6a4cee5f
MM
7204 if (GET_CODE (operands[0]) != SYMBOL_REF
7205 || (INTVAL (operands[2]) & CALL_LONG) != 0)
1fd4e8c1 7206 {
6a4cee5f
MM
7207 if (INTVAL (operands[2]) & CALL_LONG)
7208 operands[0] = rs6000_longcall_ref (operands[0]);
7209
c81bebd7 7210 if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_SOLARIS)
b6c9286a
MM
7211 emit_call_insn (gen_call_indirect_sysv (force_reg (Pmode, operands[0]),
7212 operands[1], operands[2]));
7213 else
7214 {
7215 rtx toc_reg = gen_rtx (REG, Pmode, 2);
7216 rtx toc_addr = RS6000_SAVE_TOC;
1fd4e8c1 7217
b6c9286a
MM
7218 if (DEFAULT_ABI == ABI_AIX)
7219 {
7220 /* AIX function pointers are really pointers to a three word area */
7221 rtx static_chain = gen_rtx (REG, Pmode, STATIC_CHAIN_REGNUM);
7222 emit_call_insn (gen_call_indirect_aix (force_reg (Pmode, operands[0]),
7223 operands[1], operands[2],
7224 toc_addr, toc_reg, static_chain));
7225 }
7226 else if (DEFAULT_ABI == ABI_NT)
7227 {
7228 /* NT function pointers are really pointers to a two word area */
7229 emit_call_insn (gen_call_indirect_nt (force_reg (Pmode, operands[0]),
7230 operands[1], operands[2],
7231 toc_addr, toc_reg));
7232 }
7233 else
7234 abort ();
7235 }
7236 DONE;
1fd4e8c1
RK
7237 }
7238}")
7239
7240(define_expand "call_value"
7241 [(parallel [(set (match_operand 0 "" "")
7242 (call (mem:SI (match_operand:SI 1 "address_operand" ""))
7243 (match_operand 2 "" "")))
4697a36c 7244 (use (match_operand 3 "" ""))
1fd4e8c1
RK
7245 (clobber (scratch:SI))])]
7246 ""
7247 "
7248{
7249 if (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != CONST_INT)
7250 abort ();
7251
7252 operands[1] = XEXP (operands[1], 0);
7509c759
MM
7253
7254 /* Convert NT DLL imports into an indirect call. */
7255 if (GET_CODE (operands[1]) == SYMBOL_REF
6a4cee5f 7256 && (INTVAL (operands[3]) & CALL_NT_DLLIMPORT) != 0)
7509c759
MM
7257 {
7258 operands[1] = rs6000_dll_import_ref (operands[1]);
7259 operands[3] = GEN_INT ((int)CALL_NORMAL);
7260 }
7261
6a4cee5f
MM
7262 if (GET_CODE (operands[1]) != SYMBOL_REF
7263 || (INTVAL (operands[3]) & CALL_LONG) != 0)
1fd4e8c1 7264 {
6a4cee5f
MM
7265 if (INTVAL (operands[2]) & CALL_LONG)
7266 operands[1] = rs6000_longcall_ref (operands[1]);
7267
c81bebd7 7268 if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_SOLARIS)
b6c9286a
MM
7269 emit_call_insn (gen_call_value_indirect_sysv (operands[0], operands[1],
7270 operands[2], operands[3]));
7271 else
7272 {
7273 rtx toc_reg = gen_rtx (REG, Pmode, 2);
7274 rtx toc_addr = RS6000_SAVE_TOC;
1fd4e8c1 7275
b6c9286a
MM
7276 if (DEFAULT_ABI == ABI_AIX)
7277 {
7278 /* AIX function pointers are really pointers to a three word area */
7279 rtx static_chain = gen_rtx (REG, Pmode, STATIC_CHAIN_REGNUM);
7280 emit_call_insn (gen_call_value_indirect_aix (operands[0],
7281 force_reg (Pmode, operands[1]),
7282 operands[2], operands[3],
7283 toc_addr, toc_reg, static_chain));
7284 }
7285 else if (DEFAULT_ABI == ABI_NT)
7286 {
7287 /* NT function pointers are really pointers to a two word area */
7288 emit_call_insn (gen_call_value_indirect_nt (operands[0],
7289 force_reg (Pmode, operands[1]),
7290 operands[2], operands[3],
7291 toc_addr, toc_reg));
7292 }
7293 else
7294 abort ();
7295 }
7296 DONE;
1fd4e8c1
RK
7297 }
7298}")
7299
04780ee7 7300;; Call to function in current module. No TOC pointer reload needed.
4697a36c
MM
7301;; Operand2 is non-zero if we are using the V.4 calling sequence and
7302;; either the function was not prototyped, or it was prototyped as a
7303;; variable argument function. It is > 0 if FP registers were passed
7304;; and < 0 if they were not.
04780ee7
RK
7305
7306(define_insn ""
4697a36c
MM
7307 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
7308 (match_operand 1 "" "g,g"))
7309 (use (match_operand:SI 2 "immediate_operand" "O,n"))
7310 (clobber (match_scratch:SI 3 "=l,l"))]
5a19791c 7311 "(INTVAL (operands[2]) & CALL_LONG) == 0"
4697a36c
MM
7312 "*
7313{
6a4cee5f
MM
7314 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
7315 output_asm_insn (\"crxor 6,6,6\", operands);
7316
7317 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
7318 output_asm_insn (\"creqv 6,6,6\", operands);
4697a36c
MM
7319
7320 return \"bl %z0\";
7321}"
b7ff3d82
DE
7322 [(set_attr "type" "branch")
7323 (set_attr "length" "4,8")])
04780ee7
RK
7324
7325;; Call to function which may be in another module. Restore the TOC
911f679c 7326;; pointer (r2) after the call unless this is System V.
4697a36c
MM
7327;; Operand2 is non-zero if we are using the V.4 calling sequence and
7328;; either the function was not prototyped, or it was prototyped as a
7329;; variable argument function. It is > 0 if FP registers were passed
7330;; and < 0 if they were not.
04780ee7 7331
1fd4e8c1 7332(define_insn ""
b6c9286a
MM
7333 [(call (mem:SI (match_operand:SI 0 "call_operand" "s,s"))
7334 (match_operand 1 "" "fg,fg"))
7335 (use (match_operand:SI 2 "immediate_operand" "O,n"))
7336 (clobber (match_scratch:SI 3 "=l,l"))]
6a4cee5f 7337 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
5a19791c 7338 && (INTVAL (operands[2]) & CALL_LONG) == 0"
911f679c
MM
7339 "*
7340{
b6c9286a 7341 /* Indirect calls should go through call_indirect */
0f07e76c 7342 if (GET_CODE (operands[0]) == REG)
b6c9286a 7343 abort ();
911f679c 7344
6a4cee5f
MM
7345 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
7346 output_asm_insn (\"crxor 6,6,6\", operands);
7347
7348 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
7349 output_asm_insn (\"creqv 6,6,6\", operands);
7509c759 7350
b6c9286a
MM
7351 return (TARGET_WINDOWS_NT) ? \"bl %z0\;.znop %z0\" : \"bl %z0\;%.\";
7352}"
b7ff3d82
DE
7353 [(set_attr "type" "branch")
7354 (set_attr "length" "8,12")])
59313e4e 7355
b6c9286a
MM
7356(define_insn ""
7357 [(call (mem:SI (match_operand:SI 0 "call_operand" "s,s"))
7358 (match_operand 1 "" "fg,fg"))
7359 (use (match_operand:SI 2 "immediate_operand" "O,n"))
7360 (clobber (match_scratch:SI 3 "=l,l"))]
c81bebd7 7361 "(DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
5a19791c 7362 && (INTVAL (operands[2]) & CALL_LONG) == 0"
b6c9286a
MM
7363 "*
7364{
b6c9286a 7365 /* Indirect calls should go through call_indirect */
0f07e76c 7366 if (GET_CODE (operands[0]) == REG)
b6c9286a 7367 abort ();
59313e4e 7368
6a4cee5f
MM
7369 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
7370 output_asm_insn (\"crxor 6,6,6\", operands);
7371
7372 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
7373 output_asm_insn (\"creqv 6,6,6\", operands);
7509c759 7374
58307bcd 7375 return (flag_pic == 1) ? \"bl %z0@plt\" : \"bl %z0\";
911f679c 7376}"
b7ff3d82
DE
7377 [(set_attr "type" "branch")
7378 (set_attr "length" "4,8")])
1fd4e8c1 7379
04780ee7 7380(define_insn ""
4697a36c
MM
7381 [(set (match_operand 0 "" "=fg,fg")
7382 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
7383 (match_operand 2 "" "g,g")))
7384 (use (match_operand:SI 3 "immediate_operand" "O,n"))
7385 (clobber (match_scratch:SI 4 "=l,l"))]
5a19791c 7386 "(INTVAL (operands[3]) & CALL_LONG) == 0"
4697a36c
MM
7387 "*
7388{
6a4cee5f
MM
7389 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
7390 output_asm_insn (\"crxor 6,6,6\", operands);
7391
7392 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
7393 output_asm_insn (\"creqv 6,6,6\", operands);
4697a36c
MM
7394
7395 return \"bl %z1\";
7396}"
b7ff3d82
DE
7397 [(set_attr "type" "branch")
7398 (set_attr "length" "4,8")])
04780ee7 7399
1fd4e8c1 7400(define_insn ""
b6c9286a
MM
7401 [(set (match_operand 0 "" "=fg,fg")
7402 (call (mem:SI (match_operand:SI 1 "call_operand" "s,s"))
7403 (match_operand 2 "" "fg,fg")))
7404 (use (match_operand:SI 3 "immediate_operand" "O,n"))
7405 (clobber (match_scratch:SI 4 "=l,l"))]
6a4cee5f 7406 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
5a19791c 7407 && (INTVAL (operands[3]) & CALL_LONG) == 0"
911f679c
MM
7408 "*
7409{
b6c9286a 7410 /* This should be handled by call_value_indirect */
59313e4e 7411 if (GET_CODE (operands[1]) == REG)
b6c9286a
MM
7412 abort ();
7413
6a4cee5f
MM
7414 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
7415 output_asm_insn (\"crxor 6,6,6\", operands);
7416
7417 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
7418 output_asm_insn (\"creqv 6,6,6\", operands);
7509c759 7419
b6c9286a
MM
7420 return (TARGET_WINDOWS_NT) ? \"bl %z1\;.znop %z1\" : \"bl %z1\;%.\";
7421}"
b7ff3d82
DE
7422 [(set_attr "type" "branch")
7423 (set_attr "length" "8,12")])
b6c9286a
MM
7424
7425(define_insn ""
7426 [(set (match_operand 0 "" "=fg,fg")
7427 (call (mem:SI (match_operand:SI 1 "call_operand" "s,s"))
7428 (match_operand 2 "" "fg,fg")))
7429 (use (match_operand:SI 3 "immediate_operand" "O,n"))
7430 (clobber (match_scratch:SI 4 "=l,l"))]
c81bebd7 7431 "(DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
5a19791c 7432 && (INTVAL (operands[3]) & CALL_LONG) == 0"
b6c9286a
MM
7433 "*
7434{
b6c9286a 7435 /* This should be handled by call_value_indirect */
59313e4e 7436 if (GET_CODE (operands[1]) == REG)
b6c9286a 7437 abort ();
59313e4e 7438
6a4cee5f
MM
7439 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
7440 output_asm_insn (\"crxor 6,6,6\", operands);
7441
7442 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
7443 output_asm_insn (\"creqv 6,6,6\", operands);
7509c759 7444
58307bcd 7445 return (flag_pic == 1) ? \"bl %z1@plt\" : \"bl %z1\";
911f679c 7446}"
b7ff3d82
DE
7447 [(set_attr "type" "branch")
7448 (set_attr "length" "4,8")])
e6f948e3
RK
7449
7450;; Call subroutine returning any type.
e6f948e3
RK
7451(define_expand "untyped_call"
7452 [(parallel [(call (match_operand 0 "" "")
7453 (const_int 0))
7454 (match_operand 1 "" "")
7455 (match_operand 2 "" "")])]
7456 ""
7457 "
7458{
7459 int i;
7460
4697a36c 7461 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx, const0_rtx));
e6f948e3
RK
7462
7463 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7464 {
7465 rtx set = XVECEXP (operands[2], 0, i);
7466 emit_move_insn (SET_DEST (set), SET_SRC (set));
7467 }
7468
7469 /* The optimizer does not know that the call sets the function value
7470 registers we stored in the result block. We avoid problems by
7471 claiming that all hard registers are used and clobbered at this
7472 point. */
7473 emit_insn (gen_blockage ());
7474
7475 DONE;
7476}")
7477
7478;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7479;; all of memory. This blocks insns from being moved across this point.
7480
7481(define_insn "blockage"
7482 [(unspec_volatile [(const_int 0)] 0)]
7483 ""
7484 "")
4697a36c 7485
766a866c
MM
7486;; V.4 specific code to initialize the PIC register
7487
7488(define_insn "init_v4_pic"
7489 [(set (match_operand:SI 0 "register_operand" "=l")
7490 (unspec [(const_int 0)] 7))]
c81bebd7 7491 "DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS"
eaf1bcf1 7492 "bl _GLOBAL_OFFSET_TABLE_@local-4"
63d7d7a1
MM
7493 [(set_attr "type" "branch")
7494 (set_attr "length" "4")])
766a866c 7495
1fd4e8c1
RK
7496\f
7497;; Compare insns are next. Note that the RS/6000 has two types of compares,
7e69e155 7498;; signed & unsigned, and one type of branch.
1fd4e8c1
RK
7499;;
7500;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
7501;; insns, and branches. We store the operands of compares until we see
7502;; how it is used.
7503(define_expand "cmpsi"
7504 [(set (cc0)
cd2b37d9 7505 (compare (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7506 (match_operand:SI 1 "reg_or_short_operand" "")))]
7507 ""
7508 "
7509{
7510 /* Take care of the possibility that operands[1] might be negative but
7511 this might be a logical operation. That insn doesn't exist. */
7512 if (GET_CODE (operands[1]) == CONST_INT
7513 && INTVAL (operands[1]) < 0)
7514 operands[1] = force_reg (SImode, operands[1]);
7515
7516 rs6000_compare_op0 = operands[0];
7517 rs6000_compare_op1 = operands[1];
7518 rs6000_compare_fp_p = 0;
7519 DONE;
7520}")
7521
266eb58a
DE
7522(define_expand "cmpdi"
7523 [(set (cc0)
7524 (compare (match_operand:DI 0 "gpc_reg_operand" "")
7525 (match_operand:DI 1 "reg_or_short_operand" "")))]
7526 "TARGET_POWERPC64"
7527 "
7528{
7529 /* Take care of the possibility that operands[1] might be negative but
7530 this might be a logical operation. That insn doesn't exist. */
7531 if (GET_CODE (operands[1]) == CONST_INT
7532 && INTVAL (operands[1]) < 0)
7533 operands[1] = force_reg (DImode, operands[1]);
7534
7535 rs6000_compare_op0 = operands[0];
7536 rs6000_compare_op1 = operands[1];
7537 rs6000_compare_fp_p = 0;
7538 DONE;
7539}")
7540
1fd4e8c1 7541(define_expand "cmpsf"
cd2b37d9
RK
7542 [(set (cc0) (compare (match_operand:SF 0 "gpc_reg_operand" "")
7543 (match_operand:SF 1 "gpc_reg_operand" "")))]
d14a6d05 7544 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
7545 "
7546{
7547 rs6000_compare_op0 = operands[0];
7548 rs6000_compare_op1 = operands[1];
7549 rs6000_compare_fp_p = 1;
7550 DONE;
7551}")
7552
7553(define_expand "cmpdf"
cd2b37d9
RK
7554 [(set (cc0) (compare (match_operand:DF 0 "gpc_reg_operand" "")
7555 (match_operand:DF 1 "gpc_reg_operand" "")))]
d14a6d05 7556 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
7557 "
7558{
7559 rs6000_compare_op0 = operands[0];
7560 rs6000_compare_op1 = operands[1];
7561 rs6000_compare_fp_p = 1;
7562 DONE;
7563}")
7564
7565(define_expand "beq"
7566 [(set (match_dup 2) (match_dup 1))
7567 (set (pc)
7568 (if_then_else (eq (match_dup 2)
7569 (const_int 0))
7570 (label_ref (match_operand 0 "" ""))
7571 (pc)))]
7572 ""
7573 "
7574{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7575 operands[1] = gen_rtx (COMPARE, mode,
7576 rs6000_compare_op0, rs6000_compare_op1);
7577 operands[2] = gen_reg_rtx (mode);
7578}")
7579
7580(define_expand "bne"
7581 [(set (match_dup 2) (match_dup 1))
7582 (set (pc)
7583 (if_then_else (ne (match_dup 2)
7584 (const_int 0))
7585 (label_ref (match_operand 0 "" ""))
7586 (pc)))]
7587 ""
7588 "
7589{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7590 operands[1] = gen_rtx (COMPARE, mode,
7591 rs6000_compare_op0, rs6000_compare_op1);
7592 operands[2] = gen_reg_rtx (mode);
7593}")
7594
7595(define_expand "blt"
7596 [(set (match_dup 2) (match_dup 1))
7597 (set (pc)
7598 (if_then_else (lt (match_dup 2)
7599 (const_int 0))
7600 (label_ref (match_operand 0 "" ""))
7601 (pc)))]
7602 ""
7603 "
7604{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7605 operands[1] = gen_rtx (COMPARE, mode,
7606 rs6000_compare_op0, rs6000_compare_op1);
7607 operands[2] = gen_reg_rtx (mode);
7608}")
7609
7610(define_expand "bgt"
7611 [(set (match_dup 2) (match_dup 1))
7612 (set (pc)
7613 (if_then_else (gt (match_dup 2)
7614 (const_int 0))
7615 (label_ref (match_operand 0 "" ""))
7616 (pc)))]
7617 ""
7618 "
7619{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7620 operands[1] = gen_rtx (COMPARE, mode,
7621 rs6000_compare_op0, rs6000_compare_op1);
7622 operands[2] = gen_reg_rtx (mode);
7623}")
7624
7625(define_expand "ble"
7626 [(set (match_dup 2) (match_dup 1))
7627 (set (pc)
7628 (if_then_else (le (match_dup 2)
7629 (const_int 0))
7630 (label_ref (match_operand 0 "" ""))
7631 (pc)))]
7632 ""
7633 "
7634{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7635 operands[1] = gen_rtx (COMPARE, mode,
7636 rs6000_compare_op0, rs6000_compare_op1);
7637 operands[2] = gen_reg_rtx (mode);
7638}")
7639
7640(define_expand "bge"
7641 [(set (match_dup 2) (match_dup 1))
7642 (set (pc)
7643 (if_then_else (ge (match_dup 2)
7644 (const_int 0))
7645 (label_ref (match_operand 0 "" ""))
7646 (pc)))]
7647 ""
7648 "
7649{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7650 operands[1] = gen_rtx (COMPARE, mode,
7651 rs6000_compare_op0, rs6000_compare_op1);
7652 operands[2] = gen_reg_rtx (mode);
7653}")
7654
7655(define_expand "bgtu"
7656 [(set (match_dup 2) (match_dup 1))
7657 (set (pc)
7658 (if_then_else (gtu (match_dup 2)
7659 (const_int 0))
7660 (label_ref (match_operand 0 "" ""))
7661 (pc)))]
7662 ""
7663 "
7664{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
7665 rs6000_compare_op0, rs6000_compare_op1);
7666 operands[2] = gen_reg_rtx (CCUNSmode);
7667}")
7668
7669(define_expand "bltu"
7670 [(set (match_dup 2) (match_dup 1))
7671 (set (pc)
7672 (if_then_else (ltu (match_dup 2)
7673 (const_int 0))
7674 (label_ref (match_operand 0 "" ""))
7675 (pc)))]
7676 ""
7677 "
7678{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
7679 rs6000_compare_op0, rs6000_compare_op1);
7680 operands[2] = gen_reg_rtx (CCUNSmode);
7681}")
7682
7683(define_expand "bgeu"
7684 [(set (match_dup 2) (match_dup 1))
7685 (set (pc)
7686 (if_then_else (geu (match_dup 2)
7687 (const_int 0))
7688 (label_ref (match_operand 0 "" ""))
7689 (pc)))]
7690 ""
7691 "
7692{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
7693 rs6000_compare_op0, rs6000_compare_op1);
7694 operands[2] = gen_reg_rtx (CCUNSmode);
7695}")
7696
7697(define_expand "bleu"
7698 [(set (match_dup 2) (match_dup 1))
7699 (set (pc)
7700 (if_then_else (leu (match_dup 2)
7701 (const_int 0))
7702 (label_ref (match_operand 0 "" ""))
7703 (pc)))]
7704 ""
7705 "
7706{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
7707 rs6000_compare_op0, rs6000_compare_op1);
7708 operands[2] = gen_reg_rtx (CCUNSmode);
7709}")
7710
7711;; For SNE, we would prefer that the xor/abs sequence be used for integers.
7712;; For SEQ, likewise, except that comparisons with zero should be done
7713;; with an scc insns. However, due to the order that combine see the
7714;; resulting insns, we must, in fact, allow SEQ for integers. Fail in
7715;; the cases we don't want to handle.
7716(define_expand "seq"
7717 [(set (match_dup 2) (match_dup 1))
cd2b37d9 7718 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7719 (eq:SI (match_dup 2) (const_int 0)))]
7720 ""
7721 "
7722{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7723 operands[1] = gen_rtx (COMPARE, mode,
7724 rs6000_compare_op0, rs6000_compare_op1);
7725 operands[2] = gen_reg_rtx (mode);
7726}")
7727
7728(define_expand "sne"
7729 [(set (match_dup 2) (match_dup 1))
cd2b37d9 7730 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7731 (ne:SI (match_dup 2) (const_int 0)))]
7732 ""
7733 "
7734{ if (! rs6000_compare_fp_p)
7735 FAIL;
7736
7737 operands[1] = gen_rtx (COMPARE, CCFPmode,
7738 rs6000_compare_op0, rs6000_compare_op1);
7739 operands[2] = gen_reg_rtx (CCFPmode);
7740}")
7741
7742;; A > 0 is best done using the portable sequence, so fail in that case.
7743(define_expand "sgt"
7744 [(set (match_dup 2) (match_dup 1))
cd2b37d9 7745 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7746 (gt:SI (match_dup 2) (const_int 0)))]
7747 ""
7748 "
7749{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7750
7751 if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
7752 FAIL;
7753
7754 operands[1] = gen_rtx (COMPARE, mode,
7755 rs6000_compare_op0, rs6000_compare_op1);
7756 operands[2] = gen_reg_rtx (mode);
7757}")
7758
7759;; A < 0 is best done in the portable way for A an integer.
7760(define_expand "slt"
7761 [(set (match_dup 2) (match_dup 1))
cd2b37d9 7762 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7763 (lt:SI (match_dup 2) (const_int 0)))]
7764 ""
7765 "
7766{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7767
7768 if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
7769 FAIL;
7770
7771 operands[1] = gen_rtx (COMPARE, mode,
7772 rs6000_compare_op0, rs6000_compare_op1);
7773 operands[2] = gen_reg_rtx (mode);
7774}")
7775
7776(define_expand "sge"
7777 [(set (match_dup 2) (match_dup 1))
cd2b37d9 7778 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7779 (ge:SI (match_dup 2) (const_int 0)))]
7780 ""
7781 "
7782{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7783 operands[1] = gen_rtx (COMPARE, mode,
7784 rs6000_compare_op0, rs6000_compare_op1);
7785 operands[2] = gen_reg_rtx (mode);
7786}")
7787
7788;; A <= 0 is best done the portable way for A an integer.
7789(define_expand "sle"
7790 [(set (match_dup 2) (match_dup 1))
cd2b37d9 7791 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7792 (le:SI (match_dup 2) (const_int 0)))]
7793 ""
7794 "
7795{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7796
7797 if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
7798 FAIL;
7799
7800 operands[1] = gen_rtx (COMPARE, mode,
7801 rs6000_compare_op0, rs6000_compare_op1);
7802 operands[2] = gen_reg_rtx (mode);
7803}")
7804
7805(define_expand "sgtu"
7806 [(set (match_dup 2) (match_dup 1))
cd2b37d9 7807 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7808 (gtu:SI (match_dup 2) (const_int 0)))]
7809 ""
7810 "
7811{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
7812 rs6000_compare_op0, rs6000_compare_op1);
7813 operands[2] = gen_reg_rtx (CCUNSmode);
7814}")
7815
7816(define_expand "sltu"
7817 [(set (match_dup 2) (match_dup 1))
cd2b37d9 7818 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7819 (ltu:SI (match_dup 2) (const_int 0)))]
7820 ""
7821 "
7822{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
7823 rs6000_compare_op0, rs6000_compare_op1);
7824 operands[2] = gen_reg_rtx (CCUNSmode);
7825}")
7826
7827(define_expand "sgeu"
7828 [(set (match_dup 2) (match_dup 1))
cd2b37d9 7829 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7830 (geu:SI (match_dup 2) (const_int 0)))]
7831 ""
7832 "
7833{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
7834 rs6000_compare_op0, rs6000_compare_op1);
7835 operands[2] = gen_reg_rtx (CCUNSmode);
7836}")
7837
7838(define_expand "sleu"
7839 [(set (match_dup 2) (match_dup 1))
cd2b37d9 7840 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7841 (leu:SI (match_dup 2) (const_int 0)))]
7842 ""
7843 "
7844{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
7845 rs6000_compare_op0, rs6000_compare_op1);
7846 operands[2] = gen_reg_rtx (CCUNSmode);
7847}")
7848\f
7849;; Here are the actual compare insns.
7850(define_insn ""
7851 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
cd2b37d9 7852 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
7853 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
7854 ""
7f340546 7855 "{cmp%I2|cmpw%I2} %0,%1,%2"
1fd4e8c1
RK
7856 [(set_attr "type" "compare")])
7857
266eb58a
DE
7858(define_insn ""
7859 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
7860 (compare:CC (match_operand:DI 1 "gpc_reg_operand" "r")
7861 (match_operand:DI 2 "reg_or_short_operand" "rI")))]
7862 "TARGET_POWERPC64"
7863 "cmpd%I2 %0,%1,%2"
7864 [(set_attr "type" "compare")])
7865
f357808b
RK
7866;; If we are comparing a register for equality with a large constant,
7867;; we can do this with an XOR followed by a compare. But we need a scratch
7868;; register for the result of the XOR.
7869
7870(define_split
7871 [(set (match_operand:CC 0 "cc_reg_operand" "")
cd2b37d9 7872 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
f357808b 7873 (match_operand:SI 2 "non_short_cint_operand" "")))
cd2b37d9 7874 (clobber (match_operand:SI 3 "gpc_reg_operand" ""))]
f357808b
RK
7875 "find_single_use (operands[0], insn, 0)
7876 && (GET_CODE (*find_single_use (operands[0], insn, 0)) == EQ
7877 || GET_CODE (*find_single_use (operands[0], insn, 0)) == NE)"
7878 [(set (match_dup 3) (xor:SI (match_dup 1) (match_dup 4)))
7879 (set (match_dup 0) (compare:CC (match_dup 3) (match_dup 5)))]
7880 "
7881{
7882 /* Get the constant we are comparing against, C, and see what it looks like
7883 sign-extended to 16 bits. Then see what constant could be XOR'ed
7884 with C to get the sign-extended value. */
7885
7886 int c = INTVAL (operands[2]);
7887 int sextc = (c << 16) >> 16;
7888 int xorv = c ^ sextc;
7889
7890 operands[4] = gen_rtx (CONST_INT, VOIDmode, xorv);
7891 operands[5] = gen_rtx (CONST_INT, VOIDmode, sextc);
7892}")
7893
1fd4e8c1
RK
7894(define_insn ""
7895 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
cd2b37d9 7896 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
7897 (match_operand:SI 2 "reg_or_u_short_operand" "rI")))]
7898 ""
7f340546 7899 "{cmpl%I2|cmplw%I2} %0,%1,%W2"
1fd4e8c1
RK
7900 [(set_attr "type" "compare")])
7901
266eb58a
DE
7902(define_insn ""
7903 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
7904 (compare:CCUNS (match_operand:DI 1 "gpc_reg_operand" "r")
7905 (match_operand:DI 2 "reg_or_u_short_operand" "rI")))]
7906 ""
7907 "cmpld%I2 %0,%1,%W2"
7908 [(set_attr "type" "compare")])
7909
1fd4e8c1
RK
7910;; The following two insns don't exist as single insns, but if we provide
7911;; them, we can swap an add and compare, which will enable us to overlap more
7912;; of the required delay between a compare and branch. We generate code for
7913;; them by splitting.
7914
7915(define_insn ""
7916 [(set (match_operand:CC 3 "cc_reg_operand" "=y")
cd2b37d9 7917 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 7918 (match_operand:SI 2 "short_cint_operand" "i")))
cd2b37d9 7919 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
7920 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
7921 ""
baf97f86
RK
7922 "#"
7923 [(set_attr "length" "8")])
7e69e155 7924
1fd4e8c1
RK
7925(define_insn ""
7926 [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
cd2b37d9 7927 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 7928 (match_operand:SI 2 "u_short_cint_operand" "i")))
cd2b37d9 7929 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
7930 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
7931 ""
baf97f86
RK
7932 "#"
7933 [(set_attr "length" "8")])
7e69e155 7934
1fd4e8c1
RK
7935(define_split
7936 [(set (match_operand:CC 3 "cc_reg_operand" "")
cd2b37d9 7937 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1 7938 (match_operand:SI 2 "short_cint_operand" "")))
cd2b37d9 7939 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7940 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
7941 ""
7942 [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
7943 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
7944
7945(define_split
7946 [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
cd2b37d9 7947 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1 7948 (match_operand:SI 2 "u_short_cint_operand" "")))
cd2b37d9 7949 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7950 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
7951 ""
7952 [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
7953 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
7954
7955(define_insn ""
7956 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
cd2b37d9
RK
7957 (compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "f")
7958 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 7959 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
7960 "fcmpu %0,%1,%2"
7961 [(set_attr "type" "fpcompare")])
7962
7963(define_insn ""
7964 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
cd2b37d9
RK
7965 (compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "f")
7966 (match_operand:DF 2 "gpc_reg_operand" "f")))]
d14a6d05 7967 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
7968 "fcmpu %0,%1,%2"
7969 [(set_attr "type" "fpcompare")])
7970\f
7971;; Now we have the scc insns. We can do some combinations because of the
7972;; way the machine works.
7973;;
7974;; Note that this is probably faster if we can put an insn between the
c5defebb
RK
7975;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
7976;; cases the insns below which don't use an intermediate CR field will
7977;; be used instead.
1fd4e8c1 7978(define_insn ""
cd2b37d9 7979 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
7980 (match_operator:SI 1 "scc_comparison_operator"
7981 [(match_operand 2 "cc_reg_operand" "y")
7982 (const_int 0)]))]
7983 ""
ca7f5001 7984 "%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%J1,1"
b19003d8 7985 [(set_attr "length" "12")])
1fd4e8c1
RK
7986
7987(define_insn ""
7988 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
7989 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
7990 [(match_operand 2 "cc_reg_operand" "y")
7991 (const_int 0)])
7992 (const_int 0)))
cd2b37d9 7993 (set (match_operand:SI 3 "gpc_reg_operand" "=r")
1fd4e8c1
RK
7994 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7995 ""
ca7f5001 7996 "%D1mfcr %3\;{rlinm.|rlwinm.} %3,%3,%J1,1"
b19003d8
RK
7997 [(set_attr "type" "delayed_compare")
7998 (set_attr "length" "12")])
1fd4e8c1
RK
7999
8000(define_insn ""
cd2b37d9 8001 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8002 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
8003 [(match_operand 2 "cc_reg_operand" "y")
8004 (const_int 0)])
8005 (match_operand:SI 3 "const_int_operand" "n")))]
8006 ""
8007 "*
8008{
8009 int is_bit = ccr_bit (operands[1], 1);
8010 int put_bit = 31 - (INTVAL (operands[3]) & 31);
8011 int count;
8012
8013 if (is_bit >= put_bit)
8014 count = is_bit - put_bit;
8015 else
8016 count = 32 - (put_bit - is_bit);
8017
8018 operands[4] = gen_rtx (CONST_INT, VOIDmode, count);
8019 operands[5] = gen_rtx (CONST_INT, VOIDmode, put_bit);
8020
ca7f5001 8021 return \"%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%4,%5,%5\";
b19003d8
RK
8022}"
8023 [(set_attr "length" "12")])
1fd4e8c1
RK
8024
8025(define_insn ""
8026 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
8027 (compare:CC
8028 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
8029 [(match_operand 2 "cc_reg_operand" "y")
8030 (const_int 0)])
8031 (match_operand:SI 3 "const_int_operand" "n"))
8032 (const_int 0)))
cd2b37d9 8033 (set (match_operand:SI 4 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8034 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
8035 (match_dup 3)))]
8036 ""
8037 "*
8038{
8039 int is_bit = ccr_bit (operands[1], 1);
8040 int put_bit = 31 - (INTVAL (operands[3]) & 31);
8041 int count;
8042
8043 if (is_bit >= put_bit)
8044 count = is_bit - put_bit;
8045 else
8046 count = 32 - (put_bit - is_bit);
8047
8048 operands[5] = gen_rtx (CONST_INT, VOIDmode, count);
8049 operands[6] = gen_rtx (CONST_INT, VOIDmode, put_bit);
8050
ca7f5001 8051 return \"%D1mfcr %4\;{rlinm.|rlwinm.} %4,%4,%5,%6,%6\";
1fd4e8c1 8052}"
b19003d8
RK
8053 [(set_attr "type" "delayed_compare")
8054 (set_attr "length" "12")])
1fd4e8c1 8055
c5defebb
RK
8056;; If we are comparing the result of two comparisons, this can be done
8057;; using creqv or crxor.
8058
8059(define_insn ""
8060 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
8061 (compare:CCEQ (match_operator 1 "scc_comparison_operator"
8062 [(match_operand 2 "cc_reg_operand" "y")
8063 (const_int 0)])
8064 (match_operator 3 "scc_comparison_operator"
8065 [(match_operand 4 "cc_reg_operand" "y")
8066 (const_int 0)])))]
8067 "REGNO (operands[2]) != REGNO (operands[4])"
8068 "*
8069{
8070 enum rtx_code code1, code2;
8071
8072 code1 = GET_CODE (operands[1]);
8073 code2 = GET_CODE (operands[3]);
8074
8075 if ((code1 == EQ || code1 == LT || code1 == GT
8076 || code1 == LTU || code1 == GTU
8077 || (code1 != NE && GET_MODE (operands[2]) == CCFPmode))
8078 !=
8079 (code2 == EQ || code2 == LT || code2 == GT
8080 || code2 == LTU || code2 == GTU
8081 || (code2 != NE && GET_MODE (operands[4]) == CCFPmode)))
8082 return \"%C1%C3crxor %E0,%j1,%j3\";
8083 else
8084 return \"%C1%C3creqv %E0,%j1,%j3\";
b19003d8
RK
8085}"
8086 [(set_attr "length" "12")])
c5defebb
RK
8087
8088;; There is a 3 cycle delay between consecutive mfcr instructions
8089;; so it is useful to combine 2 scc instructions to use only one mfcr.
8090
8091(define_peephole
cd2b37d9 8092 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
c5defebb
RK
8093 (match_operator:SI 1 "scc_comparison_operator"
8094 [(match_operand 2 "cc_reg_operand" "y")
8095 (const_int 0)]))
cd2b37d9 8096 (set (match_operand:SI 3 "gpc_reg_operand" "=r")
c5defebb
RK
8097 (match_operator:SI 4 "scc_comparison_operator"
8098 [(match_operand 5 "cc_reg_operand" "y")
8099 (const_int 0)]))]
8100 "REGNO (operands[2]) != REGNO (operands[5])"
ca7f5001 8101 "%D1%D4mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1"
b19003d8 8102 [(set_attr "length" "20")])
c5defebb 8103
1fd4e8c1
RK
8104;; There are some scc insns that can be done directly, without a compare.
8105;; These are faster because they don't involve the communications between
8106;; the FXU and branch units. In fact, we will be replacing all of the
8107;; integer scc insns here or in the portable methods in emit_store_flag.
8108;;
8109;; Also support (neg (scc ..)) since that construct is used to replace
8110;; branches, (plus (scc ..) ..) since that construct is common and
8111;; takes no more insns than scc, and (and (neg (scc ..)) ..) in the
8112;; cases where it is no more expensive than (neg (scc ..)).
8113
8114;; Have reload force a constant into a register for the simple insns that
8115;; otherwise won't accept constants. We do this because it is faster than
8116;; the cmp/mfcr sequence we would otherwise generate.
8117
8118(define_insn ""
cd2b37d9
RK
8119 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
8120 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1
RK
8121 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I")))
8122 (clobber (match_scratch:SI 3 "=r,&r,r,r,r"))]
8123 ""
8124 "@
ca7f5001 8125 xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
71d2371f 8126 {sfi|subfic} %3,%1,0\;{ae|adde} %0,%3,%1
ca7f5001
RK
8127 {xoril|xori} %0,%1,%b2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
8128 {xoriu|xoris} %0,%1,%u2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
8129 {sfi|subfic} %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0"
b19003d8 8130 [(set_attr "length" "12,8,12,12,12")])
1fd4e8c1
RK
8131
8132(define_insn ""
8133 [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,x,x,x")
7e69e155 8134 (compare:CC
cd2b37d9 8135 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1
RK
8136 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
8137 (const_int 0)))
cd2b37d9 8138 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
1fd4e8c1
RK
8139 (eq:SI (match_dup 1) (match_dup 2)))
8140 (clobber (match_scratch:SI 3 "=r,&r,r,r,r"))]
8141 ""
8142 "@
ca7f5001
RK
8143 xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
8144 {sfi|subfic} %3,%1,0\;{ae.|adde.} %0,%3,%1
8145 {xoril|xori} %0,%1,%b2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
8146 {xoriu|xoris} %0,%1,%u2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
8147 {sfi|subfic} %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0"
b19003d8
RK
8148 [(set_attr "type" "compare")
8149 (set_attr "length" "12,8,12,12,12")])
8150
8151;; We have insns of the form shown by the first define_insn below. If
8152;; there is something inside the comparison operation, we must split it.
8153(define_split
8154 [(set (match_operand:SI 0 "gpc_reg_operand" "")
8155 (plus:SI (match_operator 1 "comparison_operator"
8156 [(match_operand:SI 2 "" "")
8157 (match_operand:SI 3
8158 "reg_or_cint_operand" "")])
8159 (match_operand:SI 4 "gpc_reg_operand" "")))
8160 (clobber (match_operand:SI 5 "register_operand" ""))]
8161 "! gpc_reg_operand (operands[2], SImode)"
8162 [(set (match_dup 5) (match_dup 2))
8163 (set (match_dup 2) (plus:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
8164 (match_dup 4)))])
1fd4e8c1
RK
8165
8166(define_insn ""
cd2b37d9
RK
8167 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
8168 (plus:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1 8169 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
cd2b37d9 8170 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r")))
1fd4e8c1
RK
8171 (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))]
8172 ""
8173 "@
ca7f5001
RK
8174 xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
8175 {sfi|subfic} %4,%1,0\;{aze|addze} %0,%3
8176 {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
8177 {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
d9d934ef 8178 {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3"
b19003d8 8179 [(set_attr "length" "12,8,12,12,12")])
1fd4e8c1
RK
8180
8181(define_insn ""
8182 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,x")
7e69e155 8183 (compare:CC
1fd4e8c1 8184 (plus:SI
cd2b37d9 8185 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1 8186 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
cd2b37d9 8187 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r"))
1fd4e8c1
RK
8188 (const_int 0)))
8189 (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))]
8190 ""
8191 "@
ca7f5001
RK
8192 xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
8193 {sfi|subfic} %4,%1,0\;{aze.|addze.} %0,%3
8194 {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
8195 {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
8196 {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3"
b19003d8
RK
8197 [(set_attr "type" "compare")
8198 (set_attr "length" "12,8,12,12,12")])
1fd4e8c1
RK
8199
8200(define_insn ""
8201 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x,x,x,x")
7e69e155 8202 (compare:CC
1fd4e8c1 8203 (plus:SI
cd2b37d9 8204 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1 8205 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
cd2b37d9 8206 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r"))
1fd4e8c1 8207 (const_int 0)))
cd2b37d9 8208 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
1fd4e8c1
RK
8209 (plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
8210 (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))]
8211 ""
8212 "@
ca7f5001
RK
8213 xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
8214 {sfi|subfic} %4,%1,0\;{aze.|addze.} %4,%3
8215 {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
8216 {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
8217 {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3"
b19003d8
RK
8218 [(set_attr "type" "compare")
8219 (set_attr "length" "12,8,12,12,12")])
1fd4e8c1
RK
8220
8221(define_insn ""
cd2b37d9 8222 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
deb9225a 8223 (neg:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1
RK
8224 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))))]
8225 ""
8226 "@
ca7f5001
RK
8227 xor %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
8228 {ai|addic} %0,%1,-1\;{sfe|subfe} %0,%0,%0
8229 {xoril|xori} %0,%1,%b2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
8230 {xoriu|xoris} %0,%1,%u2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
8231 {sfi|subfic} %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0"
b19003d8 8232 [(set_attr "length" "12,8,12,12,12")])
1fd4e8c1 8233
ea9be077
MM
8234;; Simplify (ne X (const_int 0)) on the PowerPC. No need to on the Power,
8235;; since it nabs/sr is just as fast.
8236(define_insn ""
8237 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8238 (lshiftrt:SI (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
8239 (const_int 31)))
8240 (clobber (match_scratch:SI 2 "=&r"))]
8241 "!TARGET_POWER"
8242 "{ai|addic} %2,%1,-1\;{sfe|subfe} %0,%2,%1"
8243 [(set_attr "length" "8")])
8244
1fd4e8c1
RK
8245;; This is what (plus (ne X (const_int 0)) Y) looks like.
8246(define_insn ""
cd2b37d9 8247 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1 8248 (plus:SI (lshiftrt:SI
cd2b37d9 8249 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
1fd4e8c1 8250 (const_int 31))
cd2b37d9 8251 (match_operand:SI 2 "gpc_reg_operand" "r")))
1fd4e8c1
RK
8252 (clobber (match_scratch:SI 3 "=&r"))]
8253 ""
ca7f5001 8254 "{ai|addic} %3,%1,-1\;{aze|addze} %0,%2"
b19003d8 8255 [(set_attr "length" "8")])
1fd4e8c1
RK
8256
8257(define_insn ""
8258 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
8259 (compare:CC
8260 (plus:SI (lshiftrt:SI
cd2b37d9 8261 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
1fd4e8c1 8262 (const_int 31))
cd2b37d9 8263 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1
RK
8264 (const_int 0)))
8265 (clobber (match_scratch:SI 3 "=&r"))]
8266 ""
ca7f5001 8267 "{ai|addic} %3,%1,-1\;{aze.|addze.} %3,%2"
b19003d8
RK
8268 [(set_attr "type" "compare")
8269 (set_attr "length" "8")])
1fd4e8c1
RK
8270
8271(define_insn ""
8272 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
8273 (compare:CC
8274 (plus:SI (lshiftrt:SI
cd2b37d9 8275 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
1fd4e8c1 8276 (const_int 31))
cd2b37d9 8277 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 8278 (const_int 0)))
cd2b37d9 8279 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8280 (plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1))) (const_int 31))
8281 (match_dup 2)))
8282 (clobber (match_scratch:SI 3 "=&r"))]
8283 ""
ca7f5001 8284 "{ai|addic} %3,%1,-1\;{aze.|addze.} %0,%2"
b19003d8
RK
8285 [(set_attr "type" "compare")
8286 (set_attr "length" "8")])
1fd4e8c1
RK
8287
8288(define_insn ""
cd2b37d9
RK
8289 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8290 (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
8291 (match_operand:SI 2 "reg_or_short_operand" "r,O")))
8292 (clobber (match_scratch:SI 3 "=r,X"))]
ca7f5001 8293 "TARGET_POWER"
1fd4e8c1 8294 "@
ca7f5001 8295 doz %3,%2,%1\;{sfi|subfic} %0,%3,0\;{ae|adde} %0,%0,%3
7f340546 8296 {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{sri|srwi} %0,%0,31"
b19003d8 8297 [(set_attr "length" "12")])
1fd4e8c1
RK
8298
8299(define_insn ""
8300 [(set (match_operand:CC 4 "cc_reg_operand" "=x,x")
8301 (compare:CC
cd2b37d9 8302 (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
8303 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
8304 (const_int 0)))
cd2b37d9 8305 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
8306 (le:SI (match_dup 1) (match_dup 2)))
8307 (clobber (match_scratch:SI 3 "=r,X"))]
ca7f5001 8308 "TARGET_POWER"
1fd4e8c1 8309 "@
ca7f5001 8310 doz %3,%2,%1\;{sfi|subfic} %0,%3,0\;{ae.|adde.} %0,%0,%3
7f340546 8311 {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{sri.|srwi.} %0,%0,31"
a473029f 8312 [(set_attr "type" "compare,delayed_compare")
b19003d8 8313 (set_attr "length" "12")])
1fd4e8c1
RK
8314
8315(define_insn ""
cd2b37d9
RK
8316 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8317 (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 8318 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
cd2b37d9 8319 (match_operand:SI 3 "gpc_reg_operand" "r,r")))
1fd4e8c1 8320 (clobber (match_scratch:SI 4 "=&r,&r"))]
ca7f5001 8321 "TARGET_POWER"
1fd4e8c1 8322 "@
ca7f5001
RK
8323 doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
8324 {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze|addze} %0,%3"
b19003d8 8325 [(set_attr "length" "12")])
1fd4e8c1
RK
8326
8327(define_insn ""
8328 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
8329 (compare:CC
cd2b37d9 8330 (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 8331 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
cd2b37d9 8332 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1
RK
8333 (const_int 0)))
8334 (clobber (match_scratch:SI 4 "=&r,&r"))]
ca7f5001 8335 "TARGET_POWER"
1fd4e8c1 8336 "@
ca7f5001
RK
8337 doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
8338 {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze.|addze.} %4,%3"
b19003d8
RK
8339 [(set_attr "type" "compare")
8340 (set_attr "length" "12")])
1fd4e8c1
RK
8341
8342(define_insn ""
8343 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
8344 (compare:CC
cd2b37d9 8345 (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 8346 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
cd2b37d9 8347 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 8348 (const_int 0)))
cd2b37d9 8349 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
8350 (plus:SI (le:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
8351 (clobber (match_scratch:SI 4 "=&r,&r"))]
ca7f5001 8352 "TARGET_POWER"
1fd4e8c1 8353 "@
ca7f5001
RK
8354 doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
8355 {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze.|addze.} %0,%3"
b19003d8
RK
8356 [(set_attr "type" "compare")
8357 (set_attr "length" "12")])
1fd4e8c1
RK
8358
8359(define_insn ""
cd2b37d9
RK
8360 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8361 (neg:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 8362 (match_operand:SI 2 "reg_or_short_operand" "r,O"))))]
ca7f5001 8363 "TARGET_POWER"
1fd4e8c1 8364 "@
ca7f5001
RK
8365 doz %0,%2,%1\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
8366 {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{srai|srawi} %0,%0,31"
b19003d8 8367 [(set_attr "length" "12")])
1fd4e8c1
RK
8368
8369(define_insn ""
cd2b37d9
RK
8370 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8371 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8372 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
8373 ""
ca7f5001 8374 "{sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0"
b19003d8 8375 [(set_attr "length" "12")])
1fd4e8c1
RK
8376
8377(define_insn ""
8378 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
8379 (compare:CC
cd2b37d9 8380 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8381 (match_operand:SI 2 "reg_or_short_operand" "rI"))
8382 (const_int 0)))
cd2b37d9 8383 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8384 (leu:SI (match_dup 1) (match_dup 2)))]
8385 ""
ca7f5001 8386 "{sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0"
b19003d8
RK
8387 [(set_attr "type" "compare")
8388 (set_attr "length" "12")])
1fd4e8c1
RK
8389
8390(define_insn ""
cd2b37d9
RK
8391 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8392 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8393 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 8394 (match_operand:SI 3 "gpc_reg_operand" "r")))
1fd4e8c1
RK
8395 (clobber (match_scratch:SI 4 "=&r"))]
8396 ""
ca7f5001 8397 "{sf%I2|subf%I2c} %4,%1,%2\;{aze|addze} %0,%3"
b19003d8 8398 [(set_attr "length" "8")])
1fd4e8c1
RK
8399
8400(define_insn ""
8401 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
8402 (compare:CC
cd2b37d9 8403 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8404 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 8405 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1
RK
8406 (const_int 0)))
8407 (clobber (match_scratch:SI 4 "=&r"))]
8408 ""
ca7f5001 8409 "{sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %4,%3"
b19003d8
RK
8410 [(set_attr "type" "compare")
8411 (set_attr "length" "8")])
1fd4e8c1
RK
8412
8413(define_insn ""
8414 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
8415 (compare:CC
cd2b37d9 8416 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8417 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 8418 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1 8419 (const_int 0)))
cd2b37d9 8420 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8421 (plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
8422 (clobber (match_scratch:SI 4 "=&r"))]
8423 ""
ca7f5001 8424 "{sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %0,%3"
b19003d8
RK
8425 [(set_attr "type" "compare")
8426 (set_attr "length" "8")])
1fd4e8c1
RK
8427
8428(define_insn ""
cd2b37d9
RK
8429 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8430 (neg:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8431 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
8432 ""
ca7f5001 8433 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;nand %0,%0,%0"
b19003d8 8434 [(set_attr "length" "12")])
1fd4e8c1
RK
8435
8436(define_insn ""
cd2b37d9 8437 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1 8438 (and:SI (neg:SI
cd2b37d9 8439 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8440 (match_operand:SI 2 "reg_or_short_operand" "rI")))
cd2b37d9 8441 (match_operand:SI 3 "gpc_reg_operand" "r")))
1fd4e8c1
RK
8442 (clobber (match_scratch:SI 4 "=&r"))]
8443 ""
ca7f5001 8444 "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4"
b19003d8 8445 [(set_attr "length" "12")])
1fd4e8c1
RK
8446
8447(define_insn ""
8448 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
8449 (compare:CC
8450 (and:SI (neg:SI
cd2b37d9 8451 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8452 (match_operand:SI 2 "reg_or_short_operand" "rI")))
cd2b37d9 8453 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1
RK
8454 (const_int 0)))
8455 (clobber (match_scratch:SI 4 "=&r"))]
8456 ""
ca7f5001 8457 "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4"
b19003d8
RK
8458 [(set_attr "type" "compare")
8459 (set_attr "length" "12")])
1fd4e8c1
RK
8460
8461(define_insn ""
8462 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
8463 (compare:CC
8464 (and:SI (neg:SI
cd2b37d9 8465 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8466 (match_operand:SI 2 "reg_or_short_operand" "rI")))
cd2b37d9 8467 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1 8468 (const_int 0)))
cd2b37d9 8469 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8470 (and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))
8471 (clobber (match_scratch:SI 4 "=&r"))]
8472 ""
ca7f5001 8473 "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4"
b19003d8
RK
8474 [(set_attr "type" "compare")
8475 (set_attr "length" "12")])
1fd4e8c1
RK
8476
8477(define_insn ""
cd2b37d9
RK
8478 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8479 (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8480 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
ca7f5001 8481 "TARGET_POWER"
7f340546 8482 "doz%I2 %0,%1,%2\;nabs %0,%0\;{sri|srwi} %0,%0,31"
b19003d8 8483 [(set_attr "length" "12")])
1fd4e8c1
RK
8484
8485(define_insn ""
ad8bd902 8486 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1fd4e8c1 8487 (compare:CC
cd2b37d9 8488 (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8489 (match_operand:SI 2 "reg_or_short_operand" "rI"))
8490 (const_int 0)))
cd2b37d9 8491 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1 8492 (lt:SI (match_dup 1) (match_dup 2)))]
ca7f5001 8493 "TARGET_POWER"
7f340546 8494 "doz%I2 %0,%1,%2\;nabs %0,%0\;{sri.|srwi.} %0,%0,31"
b19003d8
RK
8495 [(set_attr "type" "delayed_compare")
8496 (set_attr "length" "12")])
1fd4e8c1
RK
8497
8498(define_insn ""
cd2b37d9
RK
8499 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8500 (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8501 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 8502 (match_operand:SI 3 "gpc_reg_operand" "r")))
1fd4e8c1 8503 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
8504 "TARGET_POWER"
8505 "doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze|addze} %0,%3"
b19003d8 8506 [(set_attr "length" "12")])
1fd4e8c1
RK
8507
8508(define_insn ""
ad8bd902 8509 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
1fd4e8c1 8510 (compare:CC
cd2b37d9 8511 (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8512 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 8513 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1
RK
8514 (const_int 0)))
8515 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
8516 "TARGET_POWER"
8517 "doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze.|addze.} %4,%3"
b19003d8
RK
8518 [(set_attr "type" "compare")
8519 (set_attr "length" "12")])
1fd4e8c1
RK
8520
8521(define_insn ""
ad8bd902 8522 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
1fd4e8c1 8523 (compare:CC
cd2b37d9 8524 (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8525 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 8526 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1 8527 (const_int 0)))
cd2b37d9 8528 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8529 (plus:SI (lt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
8530 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
8531 "TARGET_POWER"
8532 "doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze.|addze.} %0,%3"
b19003d8
RK
8533 [(set_attr "type" "compare")
8534 (set_attr "length" "12")])
1fd4e8c1
RK
8535
8536(define_insn ""
cd2b37d9
RK
8537 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8538 (neg:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8539 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
ca7f5001
RK
8540 "TARGET_POWER"
8541 "doz%I2 %0,%1,%2\;nabs %0,%0\;{srai|srawi} %0,%0,31"
b19003d8 8542 [(set_attr "length" "12")])
1fd4e8c1
RK
8543
8544(define_insn ""
cd2b37d9
RK
8545 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8546 (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
8547 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))]
8548 ""
8549 "@
ca7f5001
RK
8550 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg %0,%0
8551 {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg %0,%0"
b19003d8 8552 [(set_attr "length" "12")])
1fd4e8c1
RK
8553
8554(define_insn ""
8555 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
8556 (compare:CC
cd2b37d9 8557 (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
8558 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
8559 (const_int 0)))
cd2b37d9 8560 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
8561 (ltu:SI (match_dup 1) (match_dup 2)))]
8562 ""
8563 "@
ca7f5001
RK
8564 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg. %0,%0
8565 {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0"
b19003d8
RK
8566 [(set_attr "type" "compare")
8567 (set_attr "length" "12")])
1fd4e8c1
RK
8568
8569(define_insn ""
cd2b37d9
RK
8570 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
8571 (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
1fd4e8c1
RK
8572 (match_operand:SI 2 "reg_or_neg_short_operand" "r,r,P,P"))
8573 (match_operand:SI 3 "reg_or_short_operand" "r,I,r,I")))
8574 (clobber (match_scratch:SI 4 "=&r,r,&r,r"))]
8575 ""
8576 "@
ca7f5001
RK
8577 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
8578 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
8579 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
8580 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3"
b19003d8 8581 [(set_attr "length" "12")])
1fd4e8c1
RK
8582
8583(define_insn ""
3d91674b 8584 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
1fd4e8c1 8585 (compare:CC
3d91674b
RK
8586 (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
8587 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
8588 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 8589 (const_int 0)))
3d91674b 8590 (clobber (match_scratch:SI 4 "=&r,&r"))]
1fd4e8c1
RK
8591 ""
8592 "@
ca7f5001
RK
8593 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3
8594 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3"
b19003d8
RK
8595 [(set_attr "type" "compare")
8596 (set_attr "length" "12")])
1fd4e8c1
RK
8597
8598(define_insn ""
3d91674b 8599 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
1fd4e8c1 8600 (compare:CC
3d91674b
RK
8601 (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
8602 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
8603 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 8604 (const_int 0)))
3d91674b 8605 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1 8606 (plus:SI (ltu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
3d91674b 8607 (clobber (match_scratch:SI 4 "=&r,&r"))]
1fd4e8c1
RK
8608 ""
8609 "@
ca7f5001
RK
8610 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3
8611 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3"
b19003d8
RK
8612 [(set_attr "type" "compare")
8613 (set_attr "length" "12")])
1fd4e8c1
RK
8614
8615(define_insn ""
cd2b37d9
RK
8616 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8617 (neg:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
8618 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))))]
8619 ""
8620 "@
ca7f5001
RK
8621 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0
8622 {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0"
b19003d8 8623 [(set_attr "length" "8")])
1fd4e8c1
RK
8624
8625(define_insn ""
cd2b37d9
RK
8626 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8627 (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8628 (match_operand:SI 2 "reg_or_short_operand" "rI")))
8629 (clobber (match_scratch:SI 3 "=r"))]
ca7f5001
RK
8630 "TARGET_POWER"
8631 "doz%I2 %3,%1,%2\;{sfi|subfic} %0,%3,0\;{ae|adde} %0,%0,%3"
b19003d8 8632 [(set_attr "length" "12")])
1fd4e8c1
RK
8633
8634(define_insn ""
8635 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
8636 (compare:CC
cd2b37d9 8637 (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8638 (match_operand:SI 2 "reg_or_short_operand" "rI"))
8639 (const_int 0)))
cd2b37d9 8640 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8641 (ge:SI (match_dup 1) (match_dup 2)))
8642 (clobber (match_scratch:SI 3 "=r"))]
ca7f5001
RK
8643 "TARGET_POWER"
8644 "doz%I2 %3,%1,%2\;{sfi|subfic} %0,%3,0\;{ae.|adde.} %0,%0,%3"
b19003d8
RK
8645 [(set_attr "type" "compare")
8646 (set_attr "length" "12")])
1fd4e8c1
RK
8647
8648(define_insn ""
cd2b37d9
RK
8649 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8650 (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8651 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 8652 (match_operand:SI 3 "gpc_reg_operand" "r")))
1fd4e8c1 8653 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
8654 "TARGET_POWER"
8655 "doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3"
b19003d8 8656 [(set_attr "length" "12")])
1fd4e8c1
RK
8657
8658(define_insn ""
8659 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
8660 (compare:CC
cd2b37d9 8661 (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8662 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 8663 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1
RK
8664 (const_int 0)))
8665 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
8666 "TARGET_POWER"
8667 "doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3"
b19003d8
RK
8668 [(set_attr "type" "compare")
8669 (set_attr "length" "12")])
1fd4e8c1
RK
8670
8671(define_insn ""
8672 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
8673 (compare:CC
cd2b37d9 8674 (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8675 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 8676 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1 8677 (const_int 0)))
cd2b37d9 8678 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8679 (plus:SI (ge:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
8680 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
8681 "TARGET_POWER"
8682 "doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3"
b19003d8
RK
8683 [(set_attr "type" "compare")
8684 (set_attr "length" "12")])
1fd4e8c1
RK
8685
8686(define_insn ""
cd2b37d9
RK
8687 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8688 (neg:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8689 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
ca7f5001
RK
8690 "TARGET_POWER"
8691 "doz%I2 %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0"
b19003d8 8692 [(set_attr "length" "12")])
1fd4e8c1
RK
8693
8694;; This is (and (neg (ge X (const_int 0))) Y).
8695(define_insn ""
cd2b37d9 8696 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8697 (and:SI (neg:SI
8698 (lshiftrt:SI
cd2b37d9 8699 (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1fd4e8c1 8700 (const_int 31)))
cd2b37d9 8701 (match_operand:SI 2 "gpc_reg_operand" "r")))
1fd4e8c1
RK
8702 (clobber (match_scratch:SI 3 "=&r"))]
8703 ""
ca7f5001 8704 "{srai|srawi} %3,%1,31\;andc %0,%2,%3"
b19003d8 8705 [(set_attr "length" "8")])
1fd4e8c1
RK
8706
8707(define_insn ""
8708 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
8709 (compare:CC
8710 (and:SI (neg:SI
8711 (lshiftrt:SI
cd2b37d9 8712 (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1fd4e8c1 8713 (const_int 31)))
cd2b37d9 8714 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1
RK
8715 (const_int 0)))
8716 (clobber (match_scratch:SI 3 "=&r"))]
8717 ""
ca7f5001 8718 "{srai|srawi} %3,%1,31\;andc. %3,%2,%3"
b19003d8
RK
8719 [(set_attr "type" "compare")
8720 (set_attr "length" "8")])
1fd4e8c1
RK
8721
8722(define_insn ""
8723 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
8724 (compare:CC
8725 (and:SI (neg:SI
8726 (lshiftrt:SI
cd2b37d9 8727 (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1fd4e8c1 8728 (const_int 31)))
cd2b37d9 8729 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 8730 (const_int 0)))
cd2b37d9 8731 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8732 (and:SI (neg:SI (lshiftrt:SI (not:SI (match_dup 1))
8733 (const_int 31)))
8734 (match_dup 2)))
8735 (clobber (match_scratch:SI 3 "=&r"))]
8736 ""
ca7f5001 8737 "{srai|srawi} %3,%1,31\;andc. %0,%2,%3"
b19003d8
RK
8738 [(set_attr "type" "compare")
8739 (set_attr "length" "8")])
1fd4e8c1
RK
8740
8741(define_insn ""
cd2b37d9
RK
8742 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8743 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
8744 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))]
8745 ""
8746 "@
ca7f5001
RK
8747 {sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0
8748 {ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0"
b19003d8 8749 [(set_attr "length" "12")])
1fd4e8c1
RK
8750
8751(define_insn ""
8752 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
8753 (compare:CC
cd2b37d9 8754 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
8755 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
8756 (const_int 0)))
cd2b37d9 8757 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
8758 (geu:SI (match_dup 1) (match_dup 2)))]
8759 ""
8760 "@
ca7f5001
RK
8761 {sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0
8762 {ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0"
b19003d8
RK
8763 [(set_attr "type" "compare")
8764 (set_attr "length" "12")])
1fd4e8c1
RK
8765
8766(define_insn ""
cd2b37d9
RK
8767 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8768 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 8769 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
cd2b37d9 8770 (match_operand:SI 3 "gpc_reg_operand" "r,r")))
1fd4e8c1
RK
8771 (clobber (match_scratch:SI 4 "=&r,&r"))]
8772 ""
8773 "@
ca7f5001
RK
8774 {sf|subfc} %4,%2,%1\;{aze|addze} %0,%3
8775 {ai|addic} %4,%1,%n2\;{aze|addze} %0,%3"
b19003d8 8776 [(set_attr "length" "8")])
1fd4e8c1
RK
8777
8778(define_insn ""
8779 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
8780 (compare:CC
cd2b37d9 8781 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 8782 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
cd2b37d9 8783 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1
RK
8784 (const_int 0)))
8785 (clobber (match_scratch:SI 4 "=&r,&r"))]
8786 ""
8787 "@
ca7f5001
RK
8788 {sf|subfc} %4,%2,%1\;{aze.|addze.} %4,%3
8789 {ai|addic} %4,%1,%n2\;{aze.|addze.} %4,%3"
b19003d8
RK
8790 [(set_attr "type" "compare")
8791 (set_attr "length" "8")])
1fd4e8c1
RK
8792
8793(define_insn ""
8794 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
8795 (compare:CC
cd2b37d9 8796 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 8797 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
cd2b37d9 8798 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 8799 (const_int 0)))
cd2b37d9 8800 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
8801 (plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
8802 (clobber (match_scratch:SI 4 "=&r,&r"))]
8803 ""
8804 "@
ca7f5001
RK
8805 {sf|subfc} %4,%2,%1\;{aze.|addze.} %0,%3
8806 {ai|addic} %4,%1,%n2\;{aze.|addze.} %4,%3"
b19003d8
RK
8807 [(set_attr "type" "compare")
8808 (set_attr "length" "8")])
1fd4e8c1
RK
8809
8810(define_insn ""
cd2b37d9
RK
8811 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8812 (neg:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
8813 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))]
8814 ""
8815 "@
ca7f5001 8816 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;nand %0,%0,%0
8106dc08 8817 {sfi|subfic} %0,%1,-1\;{a%I2|add%I2c} %0,%0,%2\;{sfe|subfe} %0,%0,%0"
b19003d8 8818 [(set_attr "length" "12")])
1fd4e8c1
RK
8819
8820(define_insn ""
cd2b37d9 8821 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1 8822 (and:SI (neg:SI
cd2b37d9 8823 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 8824 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))
cd2b37d9 8825 (match_operand:SI 3 "gpc_reg_operand" "r,r")))
1fd4e8c1
RK
8826 (clobber (match_scratch:SI 4 "=&r,&r"))]
8827 ""
8828 "@
ca7f5001
RK
8829 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4
8830 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4"
b19003d8 8831 [(set_attr "length" "12")])
1fd4e8c1
RK
8832
8833(define_insn ""
8834 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
8835 (compare:CC
8836 (and:SI (neg:SI
cd2b37d9 8837 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 8838 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))
cd2b37d9 8839 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1
RK
8840 (const_int 0)))
8841 (clobber (match_scratch:SI 4 "=&r,&r"))]
8842 ""
8843 "@
ca7f5001
RK
8844 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4
8845 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4"
b19003d8
RK
8846 [(set_attr "type" "compare")
8847 (set_attr "length" "12")])
1fd4e8c1
RK
8848
8849(define_insn ""
8850 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
8851 (compare:CC
8852 (and:SI (neg:SI
cd2b37d9 8853 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 8854 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))
cd2b37d9 8855 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 8856 (const_int 0)))
cd2b37d9 8857 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
8858 (and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))
8859 (clobber (match_scratch:SI 4 "=&r,&r"))]
8860 ""
8861 "@
ca7f5001
RK
8862 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4
8863 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4"
b19003d8
RK
8864 [(set_attr "type" "compare")
8865 (set_attr "length" "12")])
1fd4e8c1
RK
8866
8867(define_insn ""
cd2b37d9
RK
8868 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8869 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8870 (const_int 0)))]
8871 ""
ca7f5001 8872 "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri|srwi} %0,%0,31"
b19003d8 8873 [(set_attr "length" "12")])
1fd4e8c1
RK
8874
8875(define_insn ""
8876 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
8877 (compare:CC
cd2b37d9 8878 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8879 (const_int 0))
8880 (const_int 0)))
cd2b37d9 8881 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8882 (gt:SI (match_dup 1) (const_int 0)))]
8883 ""
ca7f5001 8884 "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri.|srwi.} %0,%0,31"
b19003d8
RK
8885 [(set_attr "type" "delayed_compare")
8886 (set_attr "length" "12")])
1fd4e8c1
RK
8887
8888(define_insn ""
cd2b37d9
RK
8889 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8890 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8891 (match_operand:SI 2 "reg_or_short_operand" "r")))]
ca7f5001
RK
8892 "TARGET_POWER"
8893 "doz %0,%2,%1\;nabs %0,%0\;{sri|srwi} %0,%0,31"
b19003d8 8894 [(set_attr "length" "12")])
1fd4e8c1
RK
8895
8896(define_insn ""
8897 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
8898 (compare:CC
cd2b37d9 8899 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8900 (match_operand:SI 2 "reg_or_short_operand" "r"))
8901 (const_int 0)))
cd2b37d9 8902 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1 8903 (gt:SI (match_dup 1) (match_dup 2)))]
ca7f5001
RK
8904 "TARGET_POWER"
8905 "doz %0,%2,%1\;nabs %0,%0\;{sri.|srwi.} %0,%0,31"
b19003d8
RK
8906 [(set_attr "type" "delayed_compare")
8907 (set_attr "length" "12")])
1fd4e8c1
RK
8908
8909(define_insn ""
cd2b37d9
RK
8910 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8911 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8912 (const_int 0))
cd2b37d9 8913 (match_operand:SI 2 "gpc_reg_operand" "r")))
1fd4e8c1
RK
8914 (clobber (match_scratch:SI 3 "=&r"))]
8915 ""
ca7f5001 8916 "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze|addze} %0,%2"
b19003d8 8917 [(set_attr "length" "12")])
1fd4e8c1
RK
8918
8919(define_insn ""
8920 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
8921 (compare:CC
cd2b37d9 8922 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8923 (const_int 0))
cd2b37d9 8924 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1
RK
8925 (const_int 0)))
8926 (clobber (match_scratch:SI 3 "=&r"))]
8927 ""
ca7f5001 8928 "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %0,%2"
b19003d8
RK
8929 [(set_attr "type" "compare")
8930 (set_attr "length" "12")])
1fd4e8c1
RK
8931
8932(define_insn ""
8933 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
8934 (compare:CC
cd2b37d9 8935 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8936 (const_int 0))
cd2b37d9 8937 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 8938 (const_int 0)))
cd2b37d9 8939 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8940 (plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2)))
8941 (clobber (match_scratch:SI 3 "=&r"))]
8942 ""
ca7f5001 8943 "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %3,%2"
b19003d8
RK
8944 [(set_attr "type" "compare")
8945 (set_attr "length" "12")])
1fd4e8c1
RK
8946
8947(define_insn ""
cd2b37d9
RK
8948 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8949 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8950 (match_operand:SI 2 "reg_or_short_operand" "r"))
cd2b37d9 8951 (match_operand:SI 3 "gpc_reg_operand" "r")))
1fd4e8c1 8952 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
8953 "TARGET_POWER"
8954 "doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze|addze} %0,%3"
b19003d8 8955 [(set_attr "length" "12")])
1fd4e8c1
RK
8956
8957(define_insn ""
8958 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
8959 (compare:CC
cd2b37d9 8960 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8961 (match_operand:SI 2 "reg_or_short_operand" "r"))
cd2b37d9 8962 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1
RK
8963 (const_int 0)))
8964 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
8965 "TARGET_POWER"
8966 "doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze.|addze.} %4,%3"
b19003d8
RK
8967 [(set_attr "type" "compare")
8968 (set_attr "length" "12")])
1fd4e8c1
RK
8969
8970(define_insn ""
8971 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
8972 (compare:CC
cd2b37d9 8973 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8974 (match_operand:SI 2 "reg_or_short_operand" "r"))
cd2b37d9 8975 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1 8976 (const_int 0)))
cd2b37d9 8977 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8978 (plus:SI (gt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
8979 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
8980 "TARGET_POWER"
8981 "doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze.|addze.} %0,%3"
b19003d8
RK
8982 [(set_attr "type" "compare")
8983 (set_attr "length" "12")])
1fd4e8c1
RK
8984
8985(define_insn ""
cd2b37d9
RK
8986 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8987 (neg:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8988 (const_int 0))))]
8989 ""
ca7f5001 8990 "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{srai|srawi} %0,%0,31"
b19003d8 8991 [(set_attr "length" "12")])
1fd4e8c1
RK
8992
8993(define_insn ""
cd2b37d9
RK
8994 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8995 (neg:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8996 (match_operand:SI 2 "reg_or_short_operand" "r"))))]
ca7f5001
RK
8997 "TARGET_POWER"
8998 "doz %0,%2,%1\;nabs %0,%0\;{srai|srawi} %0,%0,31"
b19003d8 8999 [(set_attr "length" "12")])
1fd4e8c1
RK
9000
9001(define_insn ""
cd2b37d9
RK
9002 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9003 (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
9004 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
9005 ""
ca7f5001 9006 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg %0,%0"
b19003d8 9007 [(set_attr "length" "12")])
1fd4e8c1
RK
9008
9009(define_insn ""
9010 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
9011 (compare:CC
cd2b37d9 9012 (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
9013 (match_operand:SI 2 "reg_or_short_operand" "rI"))
9014 (const_int 0)))
cd2b37d9 9015 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
9016 (gtu:SI (match_dup 1) (match_dup 2)))]
9017 ""
ca7f5001 9018 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0"
b19003d8
RK
9019 [(set_attr "type" "compare")
9020 (set_attr "length" "12")])
1fd4e8c1
RK
9021
9022(define_insn ""
00751805
RK
9023 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
9024 (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r")
9025 (match_operand:SI 2 "reg_or_short_operand" "I,r,rI"))
9026 (match_operand:SI 3 "reg_or_short_operand" "r,r,I")))
9027 (clobber (match_scratch:SI 4 "=&r,&r,&r"))]
1fd4e8c1 9028 ""
00751805 9029 "@
ca7f5001
RK
9030 {ai|addic} %4,%1,%k2\;{aze|addze} %0,%3
9031 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
9032 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3"
b19003d8 9033 [(set_attr "length" "8,12,12")])
1fd4e8c1
RK
9034
9035(define_insn ""
3d91674b 9036 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
1fd4e8c1 9037 (compare:CC
3d91674b
RK
9038 (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
9039 (match_operand:SI 2 "reg_or_short_operand" "I,r"))
9040 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 9041 (const_int 0)))
3d91674b 9042 (clobber (match_scratch:SI 4 "=&r,&r"))]
1fd4e8c1 9043 ""
00751805 9044 "@
ca7f5001
RK
9045 {ai|addic} %4,%1,%k2\;{aze.|addze.} %0,%3
9046 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3"
b19003d8 9047 [(set_attr "type" "compare")
3d91674b 9048 (set_attr "length" "8,12")])
1fd4e8c1
RK
9049
9050(define_insn ""
3d91674b 9051 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
1fd4e8c1 9052 (compare:CC
3d91674b
RK
9053 (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
9054 (match_operand:SI 2 "reg_or_short_operand" "I,r"))
9055 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 9056 (const_int 0)))
3d91674b 9057 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1 9058 (plus:SI (gtu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
3d91674b 9059 (clobber (match_scratch:SI 4 "=&r,&r"))]
1fd4e8c1 9060 ""
00751805 9061 "@
ca7f5001
RK
9062 {ai|addic} %4,%1,%k2\;{aze.|addze.} %0,%3
9063 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3"
b19003d8 9064 [(set_attr "type" "compare")
3d91674b 9065 (set_attr "length" "8,12")])
1fd4e8c1
RK
9066
9067(define_insn ""
cd2b37d9
RK
9068 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9069 (neg:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
9070 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
9071 ""
ca7f5001 9072 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0"
b19003d8 9073 [(set_attr "length" "8")])
1fd4e8c1
RK
9074\f
9075;; Define both directions of branch and return. If we need a reload
9076;; register, we'd rather use CR0 since it is much easier to copy a
9077;; register CC value to there.
9078
9079(define_insn ""
9080 [(set (pc)
9081 (if_then_else (match_operator 1 "branch_comparison_operator"
9082 [(match_operand 2
9083 "cc_reg_operand" "x,?y")
9084 (const_int 0)])
9085 (label_ref (match_operand 0 "" ""))
9086 (pc)))]
9087 ""
b19003d8
RK
9088 "*
9089{
9090 if (get_attr_length (insn) == 8)
9091 return \"%C1bc %t1,%j1,%l0\";
9092 else
c81bebd7
MM
9093 return \"%C1bc %T1,%j1,%$+8\;b %l0\";
9094
b19003d8
RK
9095}"
9096 [(set_attr "type" "branch")])
9097
1fd4e8c1
RK
9098(define_insn ""
9099 [(set (pc)
9100 (if_then_else (match_operator 0 "branch_comparison_operator"
9101 [(match_operand 1
9102 "cc_reg_operand" "x,?y")
9103 (const_int 0)])
9104 (return)
9105 (pc)))]
9106 "direct_return ()"
ca7f5001 9107 "{%C0bcr|%C0bclr} %t0,%j0"
b7ff3d82
DE
9108 [(set_attr "type" "branch")
9109 (set_attr "length" "8")])
1fd4e8c1
RK
9110
9111(define_insn ""
9112 [(set (pc)
9113 (if_then_else (match_operator 1 "branch_comparison_operator"
9114 [(match_operand 2
9115 "cc_reg_operand" "x,?y")
9116 (const_int 0)])
9117 (pc)
9118 (label_ref (match_operand 0 "" ""))))]
9119 ""
b19003d8
RK
9120 "*
9121{
9122 if (get_attr_length (insn) == 8)
9123 return \"%C1bc %T1,%j1,%l0\";
9124 else
c81bebd7 9125 return \"%C1bc %t1,%j1,%$+8\;b %l0\";
b19003d8
RK
9126}"
9127 [(set_attr "type" "branch")])
1fd4e8c1
RK
9128
9129(define_insn ""
9130 [(set (pc)
9131 (if_then_else (match_operator 0 "branch_comparison_operator"
9132 [(match_operand 1
9133 "cc_reg_operand" "x,?y")
9134 (const_int 0)])
9135 (pc)
9136 (return)))]
9137 "direct_return ()"
ca7f5001 9138 "{%C0bcr|%C0bclr} %T0,%j0"
b7ff3d82
DE
9139 [(set_attr "type" "branch")
9140 (set_attr "length" "8")])
1fd4e8c1
RK
9141
9142;; Unconditional branch and return.
9143
9144(define_insn "jump"
9145 [(set (pc)
9146 (label_ref (match_operand 0 "" "")))]
9147 ""
b7ff3d82
DE
9148 "b %l0"
9149 [(set_attr "type" "branch")])
1fd4e8c1
RK
9150
9151(define_insn "return"
9152 [(return)]
9153 "direct_return ()"
324e52cc
TG
9154 "{br|blr}"
9155 [(set_attr "type" "jmpreg")])
1fd4e8c1
RK
9156
9157(define_insn "indirect_jump"
9158 [(set (pc) (match_operand:SI 0 "register_operand" "c,l"))]
9159 ""
9160 "@
9161 bctr
324e52cc
TG
9162 {br|blr}"
9163 [(set_attr "type" "jmpreg")])
1fd4e8c1 9164
266eb58a
DE
9165(define_insn ""
9166 [(set (pc) (match_operand:DI 0 "register_operand" "c,l"))]
9167 "TARGET_POWERPC64"
9168 "@
9169 bctr
9170 {br|blr}"
9171 [(set_attr "type" "jmpreg")])
9172
1fd4e8c1
RK
9173;; Table jump for switch statements:
9174(define_expand "tablejump"
e6ca2c17
DE
9175 [(use (match_operand 0 "" ""))
9176 (use (label_ref (match_operand 1 "" "")))]
9177 ""
9178 "
9179{
9180 if (TARGET_32BIT)
9181 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
9182 else
9183 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
9184 DONE;
9185}")
9186
9187(define_expand "tablejumpsi"
1fd4e8c1
RK
9188 [(set (match_dup 3)
9189 (plus:SI (match_operand:SI 0 "" "")
9190 (match_dup 2)))
9191 (parallel [(set (pc) (match_dup 3))
9192 (use (label_ref (match_operand 1 "" "")))])]
9193 ""
9194 "
9195{ operands[0] = force_reg (SImode, operands[0]);
9196 operands[2] = force_reg (SImode, gen_rtx (LABEL_REF, VOIDmode, operands[1]));
9197 operands[3] = gen_reg_rtx (SImode);
9198}")
9199
e6ca2c17
DE
9200(define_expand "tablejumpdi"
9201 [(set (match_dup 3)
9202 (plus:DI (match_operand:DI 0 "" "")
9203 (match_dup 2)))
9204 (parallel [(set (pc) (match_dup 3))
9205 (use (label_ref (match_operand 1 "" "")))])]
9206 ""
9207 "
9208{ operands[0] = force_reg (DImode, operands[0]);
9209 operands[2] = force_reg (DImode, gen_rtx (LABEL_REF, VOIDmode, operands[1]));
9210 operands[3] = gen_reg_rtx (DImode);
9211}")
9212
1fd4e8c1
RK
9213(define_insn ""
9214 [(set (pc)
740ab4a2 9215 (match_operand:SI 0 "register_operand" "c,l"))
1fd4e8c1
RK
9216 (use (label_ref (match_operand 1 "" "")))]
9217 ""
9218 "@
9219 bctr
a6845123
RK
9220 {br|blr}"
9221 [(set_attr "type" "jmpreg")])
1fd4e8c1 9222
266eb58a
DE
9223(define_insn ""
9224 [(set (pc)
9225 (match_operand:DI 0 "register_operand" "c,l"))
9226 (use (label_ref (match_operand 1 "" "")))]
9227 "TARGET_POWERPC64"
9228 "@
9229 bctr
9230 {br|blr}"
9231 [(set_attr "type" "jmpreg")])
9232
1fd4e8c1
RK
9233(define_insn "nop"
9234 [(const_int 0)]
9235 ""
ca7f5001 9236 "{cror 0,0,0|nop}")
1fd4e8c1 9237\f
7e69e155 9238;; Define the subtract-one-and-jump insns, starting with the template
c225ba7b
RK
9239;; so loop.c knows what to generate.
9240
b6c9286a
MM
9241(define_expand "decrement_and_branch_on_count"
9242 [(parallel [(set (pc) (if_then_else (ne (match_operand:SI 0 "register_operand" "")
c225ba7b
RK
9243 (const_int 1))
9244 (label_ref (match_operand 1 "" ""))
9245 (pc)))
b6c9286a
MM
9246 (set (match_dup 0)
9247 (plus:SI (match_dup 0)
9248 (const_int -1)))
5f81043f
RK
9249 (clobber (match_scratch:CC 2 ""))
9250 (clobber (match_scratch:SI 3 ""))])]
c225ba7b
RK
9251 ""
9252 "")
9253
1fd4e8c1
RK
9254;; We need to be able to do this for any operand, including MEM, or we
9255;; will cause reload to blow up since we don't allow output reloads on
7e69e155 9256;; JUMP_INSNs.
5f81043f
RK
9257;; In order that the length attribute is calculated correctly, the
9258;; label MUST be operand 0.
9259
1fd4e8c1
RK
9260(define_insn ""
9261 [(set (pc)
5f81043f 9262 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,*r,*r")
1fd4e8c1 9263 (const_int 1))
a6845123 9264 (label_ref (match_operand 0 "" ""))
1fd4e8c1 9265 (pc)))
5f81043f
RK
9266 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
9267 (plus:SI (match_dup 1)
9268 (const_int -1)))
1fd4e8c1
RK
9269 (clobber (match_scratch:CC 3 "=X,&x,&x"))
9270 (clobber (match_scratch:SI 4 "=X,X,r"))]
9271 ""
b19003d8
RK
9272 "*
9273{
af87a13e 9274 if (which_alternative != 0)
b19003d8
RK
9275 return \"#\";
9276 else if (get_attr_length (insn) == 8)
a6845123 9277 return \"{bdn|bdnz} %l0\";
b19003d8 9278 else
c81bebd7 9279 return \"bdz %$+8\;b %l0\";
b19003d8 9280}"
baf97f86
RK
9281 [(set_attr "type" "branch")
9282 (set_attr "length" "*,12,16")])
7e69e155 9283
5f81043f
RK
9284(define_insn ""
9285 [(set (pc)
9286 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,*r,*r")
9287 (const_int 1))
9288 (pc)
9289 (label_ref (match_operand 0 "" ""))))
9290 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
9291 (plus:SI (match_dup 1)
9292 (const_int -1)))
9293 (clobber (match_scratch:CC 3 "=X,&x,&x"))
9294 (clobber (match_scratch:SI 4 "=X,X,r"))]
9295 ""
9296 "*
9297{
9298 if (which_alternative != 0)
9299 return \"#\";
9300 else if (get_attr_length (insn) == 8)
9301 return \"bdz %l0\";
9302 else
c81bebd7 9303 return \"{bdn|bdnz} %$+8\;b %l0\";
5f81043f
RK
9304}"
9305 [(set_attr "type" "branch")
9306 (set_attr "length" "*,12,16")])
9307
c225ba7b 9308;; Similar, but we can use GE since we have a REG_NONNEG.
1fd4e8c1
RK
9309(define_insn ""
9310 [(set (pc)
5f81043f 9311 (if_then_else (ge (match_operand:SI 1 "register_operand" "c,*r,*r")
1fd4e8c1 9312 (const_int 0))
a6845123 9313 (label_ref (match_operand 0 "" ""))
1fd4e8c1 9314 (pc)))
5f81043f
RK
9315 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
9316 (plus:SI (match_dup 1)
9317 (const_int -1)))
1fd4e8c1
RK
9318 (clobber (match_scratch:CC 3 "=X,&x,&X"))
9319 (clobber (match_scratch:SI 4 "=X,X,r"))]
9320 "find_reg_note (insn, REG_NONNEG, 0)"
b19003d8
RK
9321 "*
9322{
af87a13e 9323 if (which_alternative != 0)
b19003d8
RK
9324 return \"#\";
9325 else if (get_attr_length (insn) == 8)
a6845123 9326 return \"{bdn|bdnz} %l0\";
b19003d8 9327 else
c81bebd7 9328 return \"bdz %$+8\;b %l0\";
b19003d8 9329}"
baf97f86
RK
9330 [(set_attr "type" "branch")
9331 (set_attr "length" "*,12,16")])
7e69e155 9332
1fd4e8c1
RK
9333(define_insn ""
9334 [(set (pc)
5f81043f
RK
9335 (if_then_else (ge (match_operand:SI 1 "register_operand" "c,*r,*r")
9336 (const_int 0))
9337 (pc)
9338 (label_ref (match_operand 0 "" ""))))
9339 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
9340 (plus:SI (match_dup 1)
9341 (const_int -1)))
9342 (clobber (match_scratch:CC 3 "=X,&x,&X"))
9343 (clobber (match_scratch:SI 4 "=X,X,r"))]
9344 "find_reg_note (insn, REG_NONNEG, 0)"
9345 "*
9346{
9347 if (which_alternative != 0)
9348 return \"#\";
9349 else if (get_attr_length (insn) == 8)
9350 return \"bdz %l0\";
9351 else
c81bebd7 9352 return \"{bdn|bdnz} %$+8\;b %l0\";
5f81043f
RK
9353}"
9354 [(set_attr "type" "branch")
9355 (set_attr "length" "*,12,16")])
9356
9357(define_insn ""
9358 [(set (pc)
9359 (if_then_else (eq (match_operand:SI 1 "register_operand" "c,*r,*r")
1fd4e8c1 9360 (const_int 1))
a6845123 9361 (label_ref (match_operand 0 "" ""))
1fd4e8c1 9362 (pc)))
5f81043f
RK
9363 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
9364 (plus:SI (match_dup 1)
9365 (const_int -1)))
1fd4e8c1
RK
9366 (clobber (match_scratch:CC 3 "=X,&x,&x"))
9367 (clobber (match_scratch:SI 4 "=X,X,r"))]
9368 ""
b19003d8
RK
9369 "*
9370{
af87a13e 9371 if (which_alternative != 0)
b19003d8
RK
9372 return \"#\";
9373 else if (get_attr_length (insn) == 8)
a6845123 9374 return \"bdz %l0\";
b19003d8 9375 else
c81bebd7 9376 return \"{bdn|bdnz} %$+8\;b %l0\";
b19003d8 9377}"
baf97f86
RK
9378 [(set_attr "type" "branch")
9379 (set_attr "length" "*,12,16")])
1fd4e8c1 9380
5f81043f
RK
9381(define_insn ""
9382 [(set (pc)
9383 (if_then_else (eq (match_operand:SI 1 "register_operand" "c,*r,*r")
9384 (const_int 1))
9385 (pc)
9386 (label_ref (match_operand 0 "" ""))))
9387 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
9388 (plus:SI (match_dup 1)
9389 (const_int -1)))
9390 (clobber (match_scratch:CC 3 "=X,&x,&x"))
9391 (clobber (match_scratch:SI 4 "=X,X,r"))]
9392 ""
9393 "*
9394{
9395 if (which_alternative != 0)
9396 return \"#\";
9397 else if (get_attr_length (insn) == 8)
9398 return \"{bdn|bdnz} %l0\";
9399 else
c81bebd7 9400 return \"bdz %$+8\;b %l0\";
5f81043f
RK
9401}"
9402 [(set_attr "type" "branch")
9403 (set_attr "length" "*,12,16")])
9404
1fd4e8c1
RK
9405(define_split
9406 [(set (pc)
9407 (if_then_else (match_operator 2 "comparison_operator"
cd2b37d9 9408 [(match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1
RK
9409 (const_int 1)])
9410 (match_operand 5 "" "")
9411 (match_operand 6 "" "")))
cd2b37d9 9412 (set (match_operand:SI 0 "gpc_reg_operand" "")
5f81043f
RK
9413 (plus:SI (match_dup 1)
9414 (const_int -1)))
1fd4e8c1
RK
9415 (clobber (match_scratch:CC 3 ""))
9416 (clobber (match_scratch:SI 4 ""))]
9417 "reload_completed"
9418 [(parallel [(set (match_dup 3)
5f81043f
RK
9419 (compare:CC (plus:SI (match_dup 1)
9420 (const_int -1))
1fd4e8c1 9421 (const_int 0)))
5f81043f
RK
9422 (set (match_dup 0)
9423 (plus:SI (match_dup 1)
9424 (const_int -1)))])
9425 (set (pc) (if_then_else (match_dup 7)
9426 (match_dup 5)
9427 (match_dup 6)))]
1fd4e8c1
RK
9428 "
9429{ operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3],
9430 const0_rtx); }")
9431
9432(define_split
9433 [(set (pc)
9434 (if_then_else (match_operator 2 "comparison_operator"
cd2b37d9 9435 [(match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1
RK
9436 (const_int 1)])
9437 (match_operand 5 "" "")
9438 (match_operand 6 "" "")))
9439 (set (match_operand:SI 0 "general_operand" "")
9440 (plus:SI (match_dup 1) (const_int -1)))
9441 (clobber (match_scratch:CC 3 ""))
9442 (clobber (match_scratch:SI 4 ""))]
cd2b37d9 9443 "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
1fd4e8c1 9444 [(parallel [(set (match_dup 3)
5f81043f
RK
9445 (compare:CC (plus:SI (match_dup 1)
9446 (const_int -1))
1fd4e8c1 9447 (const_int 0)))
5f81043f
RK
9448 (set (match_dup 4)
9449 (plus:SI (match_dup 1)
9450 (const_int -1)))])
9451 (set (match_dup 0)
9452 (match_dup 4))
9453 (set (pc) (if_then_else (match_dup 7)
9454 (match_dup 5)
9455 (match_dup 6)))]
1fd4e8c1
RK
9456 "
9457{ operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3],
9458 const0_rtx); }")