]> gcc.gnu.org Git - gcc.git/blame - gcc/config/rs6000/rs6000.md
Fix float conversions if sign extension in offset would occur
[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));
a7df97e6
MM
3674 output_asm_insn (\"{cau %0,%2(%1)|addis %0,%1,%2}\", xop);
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,
170e0690 3839 GEN_INT (rs6000_fpmem_offset)));
802a0058 3840
170e0690 3841 return \"stfd %0,%w2\";
802a0058
MM
3842}"
3843 [(set_attr "type" "fpstore")])
3844
3845(define_insn "*fix_truncdfsi2_load"
3846 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3847 (unspec [(reg:DI 76)
a7df97e6 3848 (match_operand:SI 1 "gpc_reg_operand" "b")] 16))]
802a0058
MM
3849 "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT"
3850 "*
3851{
a7df97e6
MM
3852 rtx indx;
3853
3854 if (rs6000_fpmem_offset > 32760)
3855 indx = operands[1];
3856 else if (frame_pointer_needed)
3857 indx = frame_pointer_rtx;
3858 else
3859 indx = stack_pointer_rtx;
3860
3861 operands[2] = gen_rtx (MEM, DFmode,
802a0058 3862 gen_rtx (PLUS, Pmode,
a7df97e6 3863 indx,
170e0690 3864 GEN_INT ((((rs6000_fpmem_offset & 0xffff) ^ 0x8000) - 0x8000)
a7df97e6 3865 + ((WORDS_BIG_ENDIAN) ? 4 : 0))));
802a0058 3866
a7df97e6 3867 return \"{l|lwz} %0,%2\";
802a0058
MM
3868}"
3869 [(set_attr "type" "load")])
3870
1fd4e8c1 3871(define_expand "fixuns_truncdfsi2"
cd2b37d9 3872 [(set (match_operand:SI 0 "gpc_reg_operand" "")
b542afe9 3873 (unsigned_fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))]
d14a6d05 3874 "! TARGET_POWER2 && ! TARGET_POWERPC && TARGET_HARD_FLOAT"
1fd4e8c1
RK
3875 "
3876{
3877 emit_insn (gen_trunc_call (operands[0], operands[1],
3c64f04b 3878 gen_rtx (SYMBOL_REF, Pmode, RS6000_UITRUNC)));
1fd4e8c1
RK
3879 DONE;
3880}")
3881
1fd4e8c1
RK
3882(define_expand "trunc_call"
3883 [(parallel [(set (match_operand:SI 0 "" "")
b542afe9 3884 (fix:SI (match_operand:DF 1 "" "")))
1fd4e8c1 3885 (use (match_operand:SI 2 "" ""))])]
d14a6d05 3886 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
3887 "
3888{
3889 rtx insns = gen_trunc_call_rtl (operands[0], operands[1], operands[2]);
3890 rtx first = XVECEXP (insns, 0, 0);
3891 rtx last = XVECEXP (insns, 0, XVECLEN (insns, 0) - 1);
3892
3893 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
3894 REG_NOTES (first));
3895 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
3896
3897 emit_insn (insns);
3898 DONE;
3899}")
3900
3901(define_expand "trunc_call_rtl"
cd2b37d9 3902 [(set (reg:DF 33) (match_operand:DF 1 "gpc_reg_operand" ""))
1fd4e8c1
RK
3903 (use (reg:DF 33))
3904 (parallel [(set (reg:SI 3)
3905 (call (mem:SI (match_operand 2 "" "")) (const_int 0)))
4697a36c 3906 (use (const_int 0))
1fd4e8c1 3907 (clobber (scratch:SI))])
cd2b37d9 3908 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1 3909 (reg:SI 3))]
d14a6d05 3910 "TARGET_HARD_FLOAT"
1fd4e8c1 3911 "
7e69e155 3912{
1fd4e8c1
RK
3913 rs6000_trunc_used = 1;
3914}")
a473029f
RK
3915
3916(define_insn "floatdidf2"
3917 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
3918 (float:DF (match_operand:DI 1 "gpc_reg_operand" "f")))]
d14a6d05 3919 "TARGET_POWERPC64 && TARGET_HARD_FLOAT"
a473029f
RK
3920 "fcfid %0,%1"
3921 [(set_attr "type" "fp")])
3922
3923(define_insn "fix_truncdfdi2"
3924 [(set (match_operand:DI 0 "gpc_reg_operand" "=f")
3925 (fix:DI (match_operand:DF 1 "gpc_reg_operand" "f")))]
d14a6d05 3926 "TARGET_POWERPC64 && TARGET_HARD_FLOAT"
a473029f
RK
3927 "fctidz %0,%1"
3928 [(set_attr "type" "fp")])
1fd4e8c1
RK
3929\f
3930;; Define the DImode operations that can be done in a small number
a6ec530c
RK
3931;; of instructions. The & constraints are to prevent the register
3932;; allocator from allocating registers that overlap with the inputs
3933;; (for example, having an input in 7,8 and an output in 6,7). We
3934;; also allow for the the output being the same as one of the inputs.
3935
266eb58a 3936(define_insn "*adddi3_noppc64"
a6ec530c
RK
3937 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r,r,r")
3938 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,0,0")
3939 (match_operand:DI 2 "reg_or_short_operand" "r,I,r,I")))]
e1f83b4d 3940 "! TARGET_POWERPC64"
0f645302
MM
3941 "*
3942{
3943 if (WORDS_BIG_ENDIAN)
3944 return (GET_CODE (operands[2])) != CONST_INT
3945 ? \"{a|addc} %L0,%L1,%L2\;{ae|adde} %0,%1,%2\"
3946 : \"{ai|addic} %L0,%L1,%2\;{a%G2e|add%G2e} %0,%1\";
3947 else
3948 return (GET_CODE (operands[2])) != CONST_INT
3949 ? \"{a|addc} %0,%1,%2\;{ae|adde} %L0,%L1,%L2\"
3950 : \"{ai|addic} %0,%1,%2\;{a%G2e|add%G2e} %L0,%L1\";
3951}"
b19003d8 3952 [(set_attr "length" "8")])
1fd4e8c1 3953
266eb58a 3954(define_insn "*subdi3_noppc64"
e7e5df70
RK
3955 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r,r,r,r")
3956 (minus:DI (match_operand:DI 1 "reg_or_short_operand" "r,I,0,r,I")
3957 (match_operand:DI 2 "gpc_reg_operand" "r,r,r,0,0")))]
266eb58a 3958 "! TARGET_POWERPC64"
5502823b
RK
3959 "*
3960{
0f645302
MM
3961 if (WORDS_BIG_ENDIAN)
3962 return (GET_CODE (operands[1]) != CONST_INT)
3963 ? \"{sf|subfc} %L0,%L2,%L1\;{sfe|subfe} %0,%2,%1\"
3964 : \"{sfi|subfic} %L0,%L2,%1\;{sf%G1e|subf%G1e} %0,%2\";
3965 else
3966 return (GET_CODE (operands[1]) != CONST_INT)
3967 ? \"{sf|subfc} %0,%2,%1\;{sfe|subfe} %L0,%L2,%L1\"
3968 : \"{sfi|subfic} %0,%2,%1\;{sf%G1e|subf%G1e} %L0,%L2\";
5502823b 3969}"
ca7f5001
RK
3970 [(set_attr "length" "8")])
3971
266eb58a 3972(define_insn "*negdi2_noppc64"
a6ec530c
RK
3973 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
3974 (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))]
51b8fc2c 3975 "! TARGET_POWERPC64"
5502823b
RK
3976 "*
3977{
3978 return (WORDS_BIG_ENDIAN)
3979 ? \"{sfi|subfic} %L0,%L1,0\;{sfze|subfze} %0,%1\"
3980 : \"{sfi|subfic} %0,%1,0\;{sfze|subfze} %L0,%L1\";
3981}"
ca7f5001
RK
3982 [(set_attr "length" "8")])
3983
8ffd9c51
RK
3984(define_expand "mulsidi3"
3985 [(set (match_operand:DI 0 "gpc_reg_operand" "")
3986 (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
3987 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))]
3988 ""
3989 "
3990{
3991 if (! TARGET_POWER && ! TARGET_POWERPC)
3992 {
4c0c634c
MM
3993 emit_move_insn (gen_rtx (REG, SImode, 3), operands[1]);
3994 emit_move_insn (gen_rtx (REG, SImode, 4), operands[2]);
fada905b 3995 emit_insn (gen_mull_call ());
cf27b467
MM
3996 if (WORDS_BIG_ENDIAN)
3997 emit_move_insn (operands[0], gen_rtx (REG, DImode, 3));
3998 else
3999 {
4000 emit_move_insn (operand_subword (operands[0], 0, 0, DImode),
4001 gen_rtx (REG, SImode, 3));
4002 emit_move_insn (operand_subword (operands[0], 1, 0, DImode),
4003 gen_rtx (REG, SImode, 4));
4004 }
8ffd9c51
RK
4005 DONE;
4006 }
4007 else if (TARGET_POWER)
4008 {
4009 emit_insn (gen_mulsidi3_mq (operands[0], operands[1], operands[2]));
4010 DONE;
4011 }
4012}")
deb9225a 4013
8ffd9c51 4014(define_insn "mulsidi3_mq"
cd2b37d9 4015 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
8ffd9c51 4016 (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
cd2b37d9 4017 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))
1fd4e8c1 4018 (clobber (match_scratch:SI 3 "=q"))]
ca7f5001 4019 "TARGET_POWER"
b19003d8 4020 "mul %0,%1,%2\;mfmq %L0"
8ffd9c51
RK
4021 [(set_attr "type" "imul")
4022 (set_attr "length" "8")])
deb9225a 4023
ebedb4dd 4024(define_insn "*mulsidi3_powerpc"
425c176f 4025 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
8ffd9c51
RK
4026 (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
4027 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
425c176f 4028 "TARGET_POWERPC && ! TARGET_POWERPC64"
5502823b
RK
4029 "*
4030{
4031 return (WORDS_BIG_ENDIAN)
4032 ? \"mulhw %0,%1,%2\;mullw %L0,%1,%2\"
4033 : \"mulhw %L0,%1,%2\;mullw %0,%1,%2\";
4034}"
8ffd9c51
RK
4035 [(set_attr "type" "imul")
4036 (set_attr "length" "8")])
deb9225a 4037
ebedb4dd
MM
4038(define_split
4039 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4040 (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
4041 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))]
cf27b467 4042 "TARGET_POWERPC && ! TARGET_POWERPC64 && reload_completed"
ebedb4dd
MM
4043 [(set (match_dup 3)
4044 (truncate:SI
4045 (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
4046 (sign_extend:DI (match_dup 2)))
4047 (const_int 32))))
4048 (set (match_dup 4)
4049 (mult:SI (match_dup 1)
4050 (match_dup 2)))]
4051 "
4052{
4053 int endian = (WORDS_BIG_ENDIAN == 0);
4054 operands[3] = operand_subword (operands[0], endian, 0, DImode);
4055 operands[4] = operand_subword (operands[0], 1 - endian, 0, DImode);
4056}")
4057
8106dc08
MM
4058(define_insn "umulsidi3"
4059 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
4060 (mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
4061 (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
4062 "TARGET_POWERPC && ! TARGET_POWERPC64"
4063 "*
4064{
4065 return (WORDS_BIG_ENDIAN)
4066 ? \"mulhwu %0,%1,%2\;mullw %L0,%1,%2\"
4067 : \"mulhwu %L0,%1,%2\;mullw %0,%1,%2\";
4068}"
4069 [(set_attr "type" "imul")
4070 (set_attr "length" "8")])
4071
ebedb4dd
MM
4072(define_split
4073 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4074 (mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
4075 (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))]
cf27b467 4076 "TARGET_POWERPC && ! TARGET_POWERPC64 && reload_completed"
ebedb4dd
MM
4077 [(set (match_dup 3)
4078 (truncate:SI
4079 (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
4080 (zero_extend:DI (match_dup 2)))
4081 (const_int 32))))
4082 (set (match_dup 4)
4083 (mult:SI (match_dup 1)
4084 (match_dup 2)))]
4085 "
4086{
4087 int endian = (WORDS_BIG_ENDIAN == 0);
4088 operands[3] = operand_subword (operands[0], endian, 0, DImode);
4089 operands[4] = operand_subword (operands[0], 1 - endian, 0, DImode);
4090}")
4091
8ffd9c51
RK
4092(define_expand "smulsi3_highpart"
4093 [(set (match_operand:SI 0 "gpc_reg_operand" "")
4094 (truncate:SI
4095 (lshiftrt:DI (mult:DI (sign_extend:DI
4096 (match_operand:SI 1 "gpc_reg_operand" "%r"))
4097 (sign_extend:DI
4098 (match_operand:SI 2 "gpc_reg_operand" "r")))
4099 (const_int 32))))]
4100 ""
4101 "
4102{
4103 if (! TARGET_POWER && ! TARGET_POWERPC)
4104 {
4105 emit_move_insn (gen_rtx (REG, SImode, 3), operands[1]);
4106 emit_move_insn (gen_rtx (REG, SImode, 4), operands[2]);
fada905b 4107 emit_insn (gen_mulh_call ());
8ffd9c51
RK
4108 emit_move_insn (operands[0], gen_rtx (REG, SImode, 3));
4109 DONE;
4110 }
4111 else if (TARGET_POWER)
4112 {
4113 emit_insn (gen_smulsi3_highpart_mq (operands[0], operands[1], operands[2]));
4114 DONE;
4115 }
4116}")
deb9225a 4117
8ffd9c51
RK
4118(define_insn "smulsi3_highpart_mq"
4119 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4120 (truncate:SI
fada905b
MM
4121 (lshiftrt:DI (mult:DI (sign_extend:DI
4122 (match_operand:SI 1 "gpc_reg_operand" "%r"))
4123 (sign_extend:DI
4124 (match_operand:SI 2 "gpc_reg_operand" "r")))
8ffd9c51
RK
4125 (const_int 32))))
4126 (clobber (match_scratch:SI 3 "=q"))]
4127 "TARGET_POWER"
4128 "mul %0,%1,%2"
4129 [(set_attr "type" "imul")])
deb9225a 4130
fada905b 4131(define_insn ""
8ffd9c51
RK
4132 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4133 (truncate:SI
fada905b
MM
4134 (lshiftrt:DI (mult:DI (sign_extend:DI
4135 (match_operand:SI 1 "gpc_reg_operand" "%r"))
4136 (sign_extend:DI
4137 (match_operand:SI 2 "gpc_reg_operand" "r")))
8ffd9c51
RK
4138 (const_int 32))))]
4139 "TARGET_POWERPC"
4140 "mulhw %0,%1,%2"
4141 [(set_attr "type" "imul")])
deb9225a 4142
266eb58a
DE
4143(define_insn "umulsi3_highpart"
4144 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4145 (truncate:SI
4146 (lshiftrt:DI (mult:DI (zero_extend:DI
4147 (match_operand:SI 1 "gpc_reg_operand" "%r"))
4148 (zero_extend:DI
4149 (match_operand:SI 2 "gpc_reg_operand" "r")))
4150 (const_int 32))))]
4151 "TARGET_POWERPC"
4152 "mulhwu %0,%1,%2"
4153 [(set_attr "type" "imul")])
4154
4155;; If operands 0 and 2 are in the same register, we have a problem. But
4156;; operands 0 and 1 (the usual case) can be in the same register. That's
4157;; why we have the strange constraints below.
4158(define_insn "ashldi3_power"
4159 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,&r")
4160 (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,0,r")
4161 (match_operand:SI 2 "reg_or_cint_operand" "M,i,r,r")))
4162 (clobber (match_scratch:SI 3 "=X,q,q,q"))]
4163 "TARGET_POWER"
4164 "@
4165 {sli|slwi} %0,%L1,%h2\;{cal %L0,0(0)|li %L0,0}
4166 sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2
4167 sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2
4168 sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2"
4169 [(set_attr "length" "8")])
4170
4171(define_insn "lshrdi3_power"
4172 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r,r,&r")
4173 (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,0,r")
4174 (match_operand:SI 2 "reg_or_cint_operand" "M,i,r,r")))
4175 (clobber (match_scratch:SI 3 "=X,q,q,q"))]
4176 "TARGET_POWER"
4177 "@
4178 {cal %0,0(0)|li %0,0}\;{s%A2i|s%A2wi} %L0,%1,%h2
4179 sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2
4180 sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2
4181 sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2"
4182 [(set_attr "length" "8")])
4183
4184;; Shift by a variable amount is too complex to be worth open-coding. We
4185;; just handle shifts by constants.
4186(define_insn "ashrdi3_power"
4187 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4188 (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
4189 (match_operand:SI 2 "const_int_operand" "M,i")))
4190 (clobber (match_scratch:SI 3 "=X,q"))]
4191 "TARGET_POWER"
4192 "@
4193 {srai|srawi} %0,%1,31\;{srai|srawi} %L0,%1,%h2
4194 sraiq %0,%1,%h2\;srliq %L0,%L1,%h2"
4195 [(set_attr "length" "8")])
4196\f
4197;; PowerPC64 DImode operations.
4198
4199(define_expand "adddi3"
4200 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4201 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "")
4202 (match_operand:DI 2 "add_operand" "")))]
4203 ""
4204 "
4205{
4206 if (! TARGET_POWERPC64 && non_add_cint_operand (operands[2], DImode))
4207 FAIL;
4208}")
4209
4210;; Discourage ai/addic because of carry but provide it in an alternative
4211;; allowing register zero as source.
4212
4213(define_insn ""
4214 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,?r,r")
4215 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,b,r,b")
4216 (match_operand:DI 2 "add_operand" "r,I,I,J")))]
4217 "TARGET_POWERPC64"
4218 "@
4219 add %0,%1,%2
4220 addi %0,%1,%2
4221 addic %0,%1,%2
802a0058 4222 addis %0,%1,%v2")
266eb58a
DE
4223
4224(define_insn ""
4225 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
4226 (compare:CC (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
4227 (match_operand:DI 2 "reg_or_short_operand" "r,I"))
4228 (const_int 0)))
4229 (clobber (match_scratch:DI 3 "=r,r"))]
4230 "TARGET_POWERPC64"
4231 "@
4232 add. %3,%1,%2
4233 addic. %3,%1,%2"
4234 [(set_attr "type" "compare")])
4235
4236(define_insn ""
4237 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
4238 (compare:CC (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
4239 (match_operand:DI 2 "reg_or_short_operand" "r,I"))
4240 (const_int 0)))
4241 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4242 (plus:DI (match_dup 1) (match_dup 2)))]
4243 "TARGET_POWERPC64"
4244 "@
4245 add. %0,%1,%2
4246 addic. %0,%1,%2"
4247 [(set_attr "type" "compare")])
4248
4249;; Split an add that we can't do in one insn into two insns, each of which
4250;; does one 16-bit part. This is used by combine. Note that the low-order
4251;; add should be last in case the result gets used in an address.
4252
4253(define_split
4254 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4255 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "")
4256 (match_operand:DI 2 "non_add_cint_operand" "")))]
4257 "TARGET_POWERPC64"
4258 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 3)))
4259 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
4260"
4261{
e6ca2c17
DE
4262 HOST_WIDE_INT low = INTVAL (operands[2]) & 0xffff;
4263 HOST_WIDE_INT high = INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff);
266eb58a
DE
4264
4265 if (low & 0x8000)
e6ca2c17 4266 high+=0x10000, low |= ((HOST_WIDE_INT) -1) << 16;
266eb58a 4267
e6ca2c17
DE
4268 operands[3] = GEN_INT (high);
4269 operands[4] = GEN_INT (low);
266eb58a
DE
4270}")
4271
4272(define_insn "one_cmpldi2"
4273 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4274 (not:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
4275 "TARGET_POWERPC64"
4276 "nor %0,%1,%1")
4277
4278(define_insn ""
4279 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4280 (compare:CC (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4281 (const_int 0)))
4282 (clobber (match_scratch:DI 2 "=r"))]
4283 "TARGET_POWERPC64"
4284 "nor. %2,%1,%1"
4285 [(set_attr "type" "compare")])
4286
4287(define_insn ""
4288 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
4289 (compare:CC (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4290 (const_int 0)))
4291 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4292 (not:DI (match_dup 1)))]
4293 "TARGET_POWERPC64"
d944f453 4294 "nor. %0,%1,%1"
266eb58a
DE
4295 [(set_attr "type" "compare")])
4296
4297(define_insn ""
4298 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4299 (minus:DI (match_operand:DI 1 "reg_or_short_operand" "r,I")
4300 (match_operand:DI 2 "gpc_reg_operand" "r,r")))]
4301 "TARGET_POWERPC64"
4302 "@
4303 subf %0,%2,%1
4304 subfic %0,%2,%1")
4305
4306(define_insn ""
4307 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4308 (compare:CC (minus:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4309 (match_operand:DI 2 "gpc_reg_operand" "r"))
4310 (const_int 0)))
4311 (clobber (match_scratch:DI 3 "=r"))]
4312 "TARGET_POWERPC64"
4313 "subf. %3,%2,%1"
4314 [(set_attr "type" "compare")])
4315
4316(define_insn ""
4317 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4318 (compare:CC (minus:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4319 (match_operand:DI 2 "gpc_reg_operand" "r"))
4320 (const_int 0)))
4321 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4322 (minus:DI (match_dup 1) (match_dup 2)))]
4323 "TARGET_POWERPC64"
4324 "subf. %0,%2,%1"
4325 [(set_attr "type" "compare")])
4326
4327(define_expand "subdi3"
4328 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4329 (minus:DI (match_operand:DI 1 "reg_or_short_operand" "")
4330 (match_operand:DI 2 "reg_or_cint_operand" "")))]
4331 ""
4332 "
4333{
4334 if (GET_CODE (operands[2]) == CONST_INT)
4335 {
4336 emit_insn (gen_adddi3 (operands[0], operands[1],
4337 negate_rtx (DImode, operands[2])));
4338 DONE;
4339 }
4340}")
4341
4342(define_insn "absdi2"
4343 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
4344 (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))
4345 (clobber (match_scratch:DI 2 "=&r,&r"))]
4346 "TARGET_POWERPC64"
4347 "sradi %2,%1,31\;xor %0,%2,%1\;subf %0,%2,%0"
4348 [(set_attr "length" "12")])
4349
4350(define_split
4351 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
4352 (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))
4353 (clobber (match_scratch:DI 2 "=&r,&r"))]
4354 "TARGET_POWERPC64 && reload_completed"
4355 [(set (match_dup 2) (ashiftrt:DI (match_dup 1) (const_int 31)))
4356 (set (match_dup 0) (xor:DI (match_dup 2) (match_dup 1)))
4357 (set (match_dup 0) (minus:DI (match_dup 2) (match_dup 0)))]
4358 "")
4359
4360(define_insn ""
4361 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
4362 (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0"))))
4363 (clobber (match_scratch:DI 2 "=&r,&r"))]
4364 "TARGET_POWERPC64"
4365 "sradi %2,%1,31\;xor %0,%2,%1\;subf %0,%0,%2"
4366 [(set_attr "length" "12")])
4367
4368(define_split
4369 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
4370 (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0"))))
4371 (clobber (match_scratch:DI 2 "=&r,&r"))]
4372 "TARGET_POWERPC64 && reload_completed"
4373 [(set (match_dup 2) (ashiftrt:DI (match_dup 1) (const_int 31)))
4374 (set (match_dup 0) (xor:DI (match_dup 2) (match_dup 1)))
4375 (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 2)))]
4376 "")
4377
4378(define_expand "negdi2"
4379 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4380 (neg:DI (match_operand:DI 1 "gpc_reg_operand" "")))]
4381 ""
4382 "")
4383
4384(define_insn ""
4385 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4386 (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
4387 "TARGET_POWERPC64"
4388 "neg %0,%1")
4389
4390(define_insn ""
4391 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4392 (compare:CC (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4393 (const_int 0)))
4394 (clobber (match_scratch:DI 2 "=r"))]
4395 "TARGET_POWERPC64"
4396 "neg. %2,%1"
4397 [(set_attr "type" "compare")])
4398
4399(define_insn ""
4400 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
4401 (compare:CC (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4402 (const_int 0)))
4403 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4404 (neg:DI (match_dup 1)))]
4405 "TARGET_POWERPC64"
4406 "neg. %0,%1"
4407 [(set_attr "type" "compare")])
4408
4409(define_insn "ffsdi2"
4410 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
4411 (ffs:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
4412 "TARGET_POWERPC64"
4413 "neg %0,%1\;and %0,%0,%1\;cntlzd %0,%0\;subfic %0,%0,64"
4414 [(set_attr "length" "16")])
4415
4416(define_insn "muldi3"
4417 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4418 (mult:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4419 (match_operand:DI 2 "gpc_reg_operand" "r")))]
4420 "TARGET_POWERPC64"
4421 "mulld %0,%1,%2"
4422 [(set_attr "type" "imul")])
4423
4424(define_insn "smuldi3_highpart"
4425 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4426 (truncate:DI
4427 (lshiftrt:TI (mult:TI (sign_extend:TI
4428 (match_operand:DI 1 "gpc_reg_operand" "%r"))
4429 (sign_extend:TI
4430 (match_operand:DI 2 "gpc_reg_operand" "r")))
4431 (const_int 64))))]
4432 "TARGET_POWERPC64"
4433 "mulhd %0,%1,%2"
4434 [(set_attr "type" "imul")])
4435
4436(define_insn "umuldi3_highpart"
4437 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4438 (truncate:DI
4439 (lshiftrt:TI (mult:TI (zero_extend:TI
4440 (match_operand:DI 1 "gpc_reg_operand" "%r"))
4441 (zero_extend:TI
4442 (match_operand:DI 2 "gpc_reg_operand" "r")))
4443 (const_int 64))))]
4444 "TARGET_POWERPC64"
4445 "mulhdu %0,%1,%2"
4446 [(set_attr "type" "imul")])
4447
4448(define_expand "divdi3"
4449 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4450 (div:DI (match_operand:DI 1 "gpc_reg_operand" "")
4451 (match_operand:DI 2 "reg_or_cint_operand" "")))]
4452 "TARGET_POWERPC64"
4453 "
4454{
4455 if (GET_CODE (operands[2]) == CONST_INT
4456 && exact_log2 (INTVAL (operands[2])) >= 0)
4457 ;
4458 else
4459 operands[2] = force_reg (DImode, operands[2]);
4460}")
4461
4462(define_expand "moddi3"
4463 [(use (match_operand:DI 0 "gpc_reg_operand" ""))
4464 (use (match_operand:DI 1 "gpc_reg_operand" ""))
4465 (use (match_operand:DI 2 "reg_or_cint_operand" ""))]
4466 "TARGET_POWERPC64"
4467 "
4468{
4469 int i = exact_log2 (INTVAL (operands[2]));
4470 rtx temp1;
4471 rtx temp2;
4472
4473 if (GET_CODE (operands[2]) != CONST_INT || i < 0)
4474 FAIL;
4475
4476 temp1 = gen_reg_rtx (DImode);
4477 temp2 = gen_reg_rtx (DImode);
4478
4479 emit_insn (gen_divdi3 (temp1, operands[1], operands[2]));
4480 emit_insn (gen_ashldi3 (temp2, temp1, GEN_INT (i)));
4481 emit_insn (gen_subdi3 (operands[0], operands[1], temp2));
4482 DONE;
4483}")
4484
4485(define_insn ""
4486 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4487 (div:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4488 (match_operand:DI 2 "const_int_operand" "N")))]
4489 "TARGET_POWERPC64 && exact_log2 (INTVAL (operands[2])) >= 0"
4490 "sradi %0,%1,%p2\;addze %0,%0"
4491 [(set_attr "length" "8")])
4492
4493(define_insn ""
4494 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4495 (compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4496 (match_operand:DI 2 "const_int_operand" "N"))
4497 (const_int 0)))
4498 (clobber (match_scratch:DI 3 "=r"))]
4499 "TARGET_POWERPC64 && exact_log2 (INTVAL (operands[2])) >= 0"
4500 "sradi %3,%1,%p2\;addze. %3,%3"
4501 [(set_attr "type" "compare")
4502 (set_attr "length" "8")])
4503
4504(define_insn ""
4505 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4506 (compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4507 (match_operand:DI 2 "const_int_operand" "N"))
4508 (const_int 0)))
4509 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4510 (div:DI (match_dup 1) (match_dup 2)))]
4511 "TARGET_POWERPC64 && exact_log2 (INTVAL (operands[2])) >= 0"
4512 "sradi %0,%1,%p2\;addze. %0,%0"
4513 [(set_attr "type" "compare")
4514 (set_attr "length" "8")])
4515
4516(define_insn ""
4517 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4518 (div:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4519 (match_operand:DI 2 "gpc_reg_operand" "r")))]
4520 "TARGET_POWERPC64"
4521 "divd %0,%1,%2"
4522 [(set_attr "type" "idiv")])
4523
4524(define_insn "udivdi3"
4525 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4526 (udiv:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4527 (match_operand:DI 2 "gpc_reg_operand" "r")))]
4528 "TARGET_POWERPC64"
4529 "divdu %0,%1,%2"
4530 [(set_attr "type" "idiv")])
4531
4532(define_insn "rotldi3"
4533 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4534 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4535 (match_operand:DI 2 "reg_or_cint_operand" "ri")))]
4536 "TARGET_POWERPC64"
a66078ee 4537 "rld%I2cl %0,%1,%H2,0")
266eb58a
DE
4538
4539(define_insn ""
4540 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4541 (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4542 (match_operand:DI 2 "reg_or_cint_operand" "ri"))
4543 (const_int 0)))
4544 (clobber (match_scratch:DI 3 "=r"))]
4545 "TARGET_POWERPC64"
a66078ee 4546 "rld%I2cl. %3,%1,%H2,0"
266eb58a
DE
4547 [(set_attr "type" "delayed_compare")])
4548
4549(define_insn ""
4550 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4551 (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4552 (match_operand:DI 2 "reg_or_cint_operand" "ri"))
4553 (const_int 0)))
4554 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4555 (rotate:DI (match_dup 1) (match_dup 2)))]
4556 "TARGET_POWERPC64"
a66078ee 4557 "rld%I2cl. %0,%1,%H2,0"
266eb58a
DE
4558 [(set_attr "type" "delayed_compare")])
4559
4560(define_expand "ashldi3"
4561 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4562 (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
4563 (match_operand:SI 2 "reg_or_cint_operand" "")))]
4564 "TARGET_POWERPC64 || TARGET_POWER"
4565 "
4566{
4567 if (TARGET_POWERPC64)
4568 ;
4569 else if (TARGET_POWER)
4570 {
4571 emit_insn (gen_ashldi3_power (operands[0], operands[1], operands[2]));
4572 DONE;
4573 }
4574 else
4575 FAIL;
4576}")
4577
4578(define_insn ""
4579 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4580 (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4581 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
4582 "TARGET_POWERPC64"
a66078ee 4583 "sld%I2 %0,%1,%H2"
266eb58a
DE
4584 [(set_attr "length" "8")])
4585
4586(define_insn ""
4587 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4588 (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4589 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
4590 (const_int 0)))
4591 (clobber (match_scratch:DI 3 "=r"))]
4592 "TARGET_POWERPC64"
a66078ee 4593 "sld%I2. %3,%1,%H2"
266eb58a
DE
4594 [(set_attr "type" "delayed_compare")])
4595
4596(define_insn ""
4597 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4598 (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4599 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
4600 (const_int 0)))
4601 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4602 (ashift:DI (match_dup 1) (match_dup 2)))]
4603 "TARGET_POWERPC64"
a66078ee 4604 "sld%I2. %0,%1,%H2"
266eb58a
DE
4605 [(set_attr "type" "delayed_compare")])
4606
4607(define_expand "lshrdi3"
4608 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4609 (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
4610 (match_operand:SI 2 "reg_or_cint_operand" "")))]
4611 "TARGET_POWERPC64 || TARGET_POWER"
4612 "
4613{
4614 if (TARGET_POWERPC64)
4615 ;
4616 else if (TARGET_POWER)
4617 {
4618 emit_insn (gen_lshrdi3_power (operands[0], operands[1], operands[2]));
4619 DONE;
4620 }
4621 else
4622 FAIL;
4623}")
4624
4625(define_insn ""
4626 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4627 (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4628 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
4629 "TARGET_POWERPC64"
a66078ee 4630 "srd%I2 %0,%1,%H2")
266eb58a
DE
4631
4632(define_insn ""
4633 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4634 (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4635 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
4636 (const_int 0)))
4637 (clobber (match_scratch:DI 3 "=r"))]
4638 "TARGET_POWERPC64"
a66078ee 4639 "srd%I2. %3,%1,%H2"
266eb58a
DE
4640 [(set_attr "type" "delayed_compare")])
4641
4642(define_insn ""
4643 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4644 (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4645 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
4646 (const_int 0)))
4647 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4648 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
4649 "TARGET_POWERPC64"
a66078ee 4650 "srd%I2. %0,%1,%H2"
266eb58a
DE
4651 [(set_attr "type" "delayed_compare")])
4652
4653(define_expand "ashrdi3"
4654 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4655 (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
4656 (match_operand:SI 2 "reg_or_cint_operand" "")))]
4657 "TARGET_POWERPC64 || TARGET_POWER"
4658 "
4659{
4660 if (TARGET_POWERPC64)
4661 ;
4662 else if (TARGET_POWER && GET_CODE (operands[2]) == CONST_INT)
4663 {
4664 emit_insn (gen_ashrdi3_power (operands[0], operands[1], operands[2]));
4665 DONE;
4666 }
4667 else
4668 FAIL;
4669}")
4670
4671(define_insn ""
4672 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4673 (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4674 (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
4675 "TARGET_POWERPC64"
375490e0 4676 "srad%I2 %0,%1,%H2")
266eb58a
DE
4677
4678(define_insn ""
4679 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4680 (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4681 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
4682 (const_int 0)))
4683 (clobber (match_scratch:DI 3 "=r"))]
4684 "TARGET_POWERPC64"
375490e0 4685 "srad%I2. %3,%1,%H2"
266eb58a
DE
4686 [(set_attr "type" "delayed_compare")])
4687
4688(define_insn ""
4689 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4690 (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
4691 (match_operand:SI 2 "reg_or_cint_operand" "ri"))
4692 (const_int 0)))
4693 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4694 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
4695 "TARGET_POWERPC64"
375490e0 4696 "srad%I2. %0,%1,%H2"
266eb58a
DE
4697 [(set_attr "type" "delayed_compare")])
4698
4699(define_insn "anddi3"
4700 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
4701 (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r")
4702 (match_operand:DI 2 "and_operand" "?r,K,J")))
4703 (clobber (match_scratch:CC 3 "=X,x,x"))]
4704 "TARGET_POWERPC64"
4705 "@
4706 and %0,%1,%2
4707 andi. %0,%1,%b2
4708 andis. %0,%1,%u2")
4709
4710(define_insn ""
4711 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x")
4712 (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r")
4713 (match_operand:DI 2 "and_operand" "r,K,J"))
4714 (const_int 0)))
4715 (clobber (match_scratch:DI 3 "=r,r,r"))]
4716 "TARGET_POWERPC64"
4717 "@
4718 and. %3,%1,%2
4719 andi. %3,%1,%b2
4720 andis. %3,%1,%u2"
4721 [(set_attr "type" "compare,compare,compare")])
4722
4723(define_insn ""
4724 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x")
4725 (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r")
4726 (match_operand:DI 2 "and_operand" "r,K,J"))
4727 (const_int 0)))
4728 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
4729 (and:DI (match_dup 1) (match_dup 2)))]
4730 "TARGET_POWERPC64"
4731 "@
4732 and. %0,%1,%2
4733 andi. %0,%1,%b2
4734 andis. %0,%1,%u2"
4735 [(set_attr "type" "compare,compare,compare")])
4736
4737;; Take a AND with a constant that cannot be done in a single insn and try to
4738;; split it into two insns. This does not verify that the insns are valid
4739;; since this need not be done as combine will do it.
4740
4741(define_split
4742 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4743 (and:DI (match_operand:DI 1 "gpc_reg_operand" "")
4744 (match_operand:DI 2 "non_and_cint_operand" "")))]
4745 "TARGET_POWERPC64"
4746 [(set (match_dup 0) (and:DI (match_dup 1) (match_dup 3)))
4747 (set (match_dup 0) (and:DI (match_dup 0) (match_dup 4)))]
4748 "
4749{
4750 int maskval = INTVAL (operands[2]);
4751 int i, transitions, last_bit_value;
4752 int orig = maskval, first_c = maskval, second_c;
4753
4754 /* We know that MASKVAL must have more than 2 bit-transitions. Start at
4755 the low-order bit and count for the third transition. When we get there,
4756 make a first mask that has everything to the left of that position
4757 a one. Then make the second mask to turn off whatever else is needed. */
4758
4759 for (i = 1, transitions = 0, last_bit_value = maskval & 1; i < 32; i++)
4760 {
4761 if (((maskval >>= 1) & 1) != last_bit_value)
4762 last_bit_value ^= 1, transitions++;
4763
4764 if (transitions > 2)
4765 {
4766 first_c |= (~0) << i;
4767 break;
4768 }
4769 }
4770
4771 second_c = orig | ~ first_c;
4772
4773 operands[3] = gen_rtx (CONST_INT, VOIDmode, first_c);
4774 operands[4] = gen_rtx (CONST_INT, VOIDmode, second_c);
4775}")
4776
4777(define_insn "iordi3"
4778 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
4779 (ior:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r")
4780 (match_operand:DI 2 "logical_operand" "r,K,J")))]
4781 "TARGET_POWERPC64"
4782 "@
4783 or %0,%1,%2
4784 ori %0,%1,%b2
4785 oris %0,%1,%u2")
4786
4787(define_insn ""
4788 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4789 (compare:CC (ior:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4790 (match_operand:DI 2 "gpc_reg_operand" "r"))
4791 (const_int 0)))
4792 (clobber (match_scratch:DI 3 "=r"))]
4793 "TARGET_POWERPC64"
4794 "or. %3,%1,%2"
4795 [(set_attr "type" "compare")])
4796
4797(define_insn ""
4798 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4799 (compare:CC (ior:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4800 (match_operand:DI 2 "gpc_reg_operand" "r"))
4801 (const_int 0)))
4802 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4803 (ior:DI (match_dup 1) (match_dup 2)))]
4804 "TARGET_POWERPC64"
4805 "or. %0,%1,%2"
4806 [(set_attr "type" "compare")])
4807
4808;; Split an IOR that we can't do in one insn into two insns, each of which
4809;; does one 16-bit part. This is used by combine.
4810
4811(define_split
4812 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4813 (ior:DI (match_operand:DI 1 "gpc_reg_operand" "")
4814 (match_operand:DI 2 "non_logical_cint_operand" "")))]
4815 "TARGET_POWERPC64"
4816 [(set (match_dup 0) (ior:DI (match_dup 1) (match_dup 3)))
4817 (set (match_dup 0) (ior:DI (match_dup 0) (match_dup 4)))]
4818"
4819{
4820 operands[3] = gen_rtx (CONST_INT, VOIDmode,
e6ca2c17 4821 INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff));
266eb58a
DE
4822 operands[4] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0xffff);
4823}")
1fd4e8c1 4824
266eb58a
DE
4825(define_insn "xordi3"
4826 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
4827 (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r")
4828 (match_operand:DI 2 "logical_operand" "r,K,J")))]
4829 "TARGET_POWERPC64"
1fd4e8c1 4830 "@
266eb58a
DE
4831 xor %0,%1,%2
4832 xori %0,%1,%b2
4833 xoris %0,%1,%u2")
1fd4e8c1 4834
266eb58a
DE
4835(define_insn ""
4836 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4837 (compare:CC (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4838 (match_operand:DI 2 "gpc_reg_operand" "r"))
4839 (const_int 0)))
4840 (clobber (match_scratch:DI 3 "=r"))]
4841 "TARGET_POWERPC64"
4842 "xor. %3,%1,%2"
4843 [(set_attr "type" "compare")])
1fd4e8c1 4844
266eb58a
DE
4845(define_insn ""
4846 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4847 (compare:CC (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4848 (match_operand:DI 2 "gpc_reg_operand" "r"))
4849 (const_int 0)))
4850 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4851 (xor:DI (match_dup 1) (match_dup 2)))]
4852 "TARGET_POWERPC64"
4853 "xor. %0,%1,%2"
4854 [(set_attr "type" "compare")])
1fd4e8c1 4855
266eb58a
DE
4856;; Split an XOR that we can't do in one insn into two insns, each of which
4857;; does one 16-bit part. This is used by combine.
4858
4859(define_split
4860 [(set (match_operand:DI 0 "gpc_reg_operand" "")
4861 (xor:DI (match_operand:DI 1 "gpc_reg_operand" "")
4862 (match_operand:DI 2 "non_logical_cint_operand" "")))]
4863 "TARGET_POWERPC64"
4864 [(set (match_dup 0) (xor:DI (match_dup 1) (match_dup 3)))
4865 (set (match_dup 0) (xor:DI (match_dup 0) (match_dup 4)))]
4866"
4867{
4868 operands[3] = gen_rtx (CONST_INT, VOIDmode,
4869 INTVAL (operands[2]) & 0xffff0000);
4870 operands[4] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0xffff);
1fd4e8c1
RK
4871}")
4872
2bee0449 4873(define_insn ""
266eb58a
DE
4874 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4875 (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4876 (match_operand:DI 2 "gpc_reg_operand" "r"))))]
4877 "TARGET_POWERPC64"
4878 "eqv %0,%1,%2")
a473029f 4879
266eb58a
DE
4880(define_insn ""
4881 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4882 (compare:CC (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4883 (match_operand:DI 2 "gpc_reg_operand" "r")))
4884 (const_int 0)))
4885 (clobber (match_scratch:DI 3 "=r"))]
4886 "TARGET_POWERPC64"
4887 "eqv. %3,%1,%2"
4888 [(set_attr "type" "compare")])
a473029f 4889
266eb58a
DE
4890(define_insn ""
4891 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4892 (compare:CC (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
4893 (match_operand:DI 2 "gpc_reg_operand" "r")))
4894 (const_int 0)))
4895 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4896 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
4897 "TARGET_POWERPC64"
4898 "eqv. %0,%1,%2"
4899 [(set_attr "type" "compare")])
4900
4901(define_insn ""
a473029f 4902 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
266eb58a
DE
4903 (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4904 (match_operand:DI 2 "gpc_reg_operand" "r")))]
a473029f 4905 "TARGET_POWERPC64"
266eb58a 4906 "andc %0,%2,%1")
a473029f 4907
266eb58a
DE
4908(define_insn ""
4909 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4910 (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4911 (match_operand:DI 2 "gpc_reg_operand" "r"))
4912 (const_int 0)))
4913 (clobber (match_scratch:DI 3 "=r"))]
a473029f 4914 "TARGET_POWERPC64"
266eb58a
DE
4915 "andc. %3,%2,%1"
4916 [(set_attr "type" "compare")])
a473029f 4917
266eb58a
DE
4918(define_insn ""
4919 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4920 (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4921 (match_operand:DI 2 "gpc_reg_operand" "r"))
4922 (const_int 0)))
4923 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4924 (and:DI (not:DI (match_dup 1)) (match_dup 2)))]
a473029f 4925 "TARGET_POWERPC64"
266eb58a
DE
4926 "andc. %0,%2,%1"
4927 [(set_attr "type" "compare")])
a473029f 4928
266eb58a 4929(define_insn ""
a473029f 4930 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
266eb58a
DE
4931 (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4932 (match_operand:DI 2 "gpc_reg_operand" "r")))]
a473029f 4933 "TARGET_POWERPC64"
266eb58a 4934 "orc %0,%2,%1")
a473029f 4935
266eb58a
DE
4936(define_insn ""
4937 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4938 (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4939 (match_operand:DI 2 "gpc_reg_operand" "r"))
4940 (const_int 0)))
4941 (clobber (match_scratch:DI 3 "=r"))]
4942 "TARGET_POWERPC64"
4943 "orc. %3,%2,%1"
4944 [(set_attr "type" "compare")])
4945
4946(define_insn ""
4947 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4948 (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
4949 (match_operand:DI 2 "gpc_reg_operand" "r"))
4950 (const_int 0)))
4951 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4952 (ior:DI (not:DI (match_dup 1)) (match_dup 2)))]
4953 "TARGET_POWERPC64"
4954 "orc. %0,%2,%1"
4955 [(set_attr "type" "compare")])
4956
4957(define_insn ""
a473029f 4958 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
266eb58a
DE
4959 (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
4960 (not:DI (match_operand:DI 2 "gpc_reg_operand" "r"))))]
a473029f 4961 "TARGET_POWERPC64"
266eb58a 4962 "nand %0,%1,%2")
a473029f 4963
266eb58a
DE
4964(define_insn ""
4965 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
4966 (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
4967 (not:DI (match_operand:DI 2 "gpc_reg_operand" "r")))
4968 (const_int 0)))
4969 (clobber (match_scratch:DI 3 "=r"))]
4970 "TARGET_POWERPC64"
4971 "nand. %3,%1,%2"
4972 [(set_attr "type" "compare")])
4973
4974(define_insn ""
4975 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
4976 (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
4977 (not:DI (match_operand:DI 2 "gpc_reg_operand" "r")))
4978 (const_int 0)))
4979 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
4980 (ior:DI (not:DI (match_dup 1)) (not:DI (match_dup 2))))]
4981 "TARGET_POWERPC64"
4982 "nand. %0,%1,%2"
4983 [(set_attr "type" "compare")])
4984
4985(define_insn ""
a473029f 4986 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
266eb58a
DE
4987 (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
4988 (not:DI (match_operand:DI 2 "gpc_reg_operand" "r"))))]
a473029f 4989 "TARGET_POWERPC64"
266eb58a 4990 "nor %0,%1,%2")
a473029f
RK
4991
4992(define_insn ""
4993 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
266eb58a
DE
4994 (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
4995 (not:DI (match_operand:DI 2 "gpc_reg_operand" "r")))
a473029f
RK
4996 (const_int 0)))
4997 (clobber (match_scratch:DI 3 "=r"))]
4998 "TARGET_POWERPC64"
266eb58a
DE
4999 "nor. %3,%1,%2"
5000 [(set_attr "type" "compare")])
a473029f
RK
5001
5002(define_insn ""
5003 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
266eb58a
DE
5004 (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
5005 (not:DI (match_operand:DI 2 "gpc_reg_operand" "r")))
a473029f
RK
5006 (const_int 0)))
5007 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
266eb58a 5008 (and:DI (not:DI (match_dup 1)) (not:DI (match_dup 2))))]
a473029f 5009 "TARGET_POWERPC64"
266eb58a
DE
5010 "nor. %0,%1,%2"
5011 [(set_attr "type" "compare")])
a473029f 5012\f
1fd4e8c1 5013;; Now define ways of moving data around.
4697a36c
MM
5014
5015;; Elf specific ways of loading addresses for non-PIC code.
5016;; The output of this could be r0, but we limit it to base
5017;; registers, since almost all uses of this will need it
5018;; in a base register shortly.
5019(define_insn "elf_high"
5020 [(set (match_operand:SI 0 "register_operand" "=b")
5021 (high:SI (match_operand 1 "" "")))]
5022 "TARGET_ELF && !TARGET_64BIT"
5023 "{cau|addis} %0,0,%1@ha")
5024
5025(define_insn "elf_low"
5026 [(set (match_operand:SI 0 "register_operand" "=r")
5027 (lo_sum:SI (match_operand:SI 1 "register_operand" "b")
5028 (match_operand 2 "" "")))]
5029 "TARGET_ELF && !TARGET_64BIT"
5030 "{cal %0,%a2@l(%1)|addi %0,%1,%2@l}")
5031
766a866c
MM
5032;; Set up a register with a value from the GOT table
5033
5034(define_expand "movsi_got"
5035 [(set (match_operand:SI 0 "register_operand" "")
5036 (unspec [(match_operand:SI 1 "got_operand" "")
5037 (match_dup 2)] 8))]
c81bebd7 5038 "(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) && flag_pic"
766a866c
MM
5039 "
5040{
c4c40373 5041 operands[2] = rs6000_got_register (operands[1]);
766a866c
MM
5042}")
5043
84f414bc 5044(define_insn "*movsi_got_internal"
766a866c
MM
5045 [(set (match_operand:SI 0 "register_operand" "=r")
5046 (unspec [(match_operand:SI 1 "got_operand" "")
5047 (match_operand:SI 2 "register_operand" "b")] 8))]
c81bebd7 5048 "(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) && flag_pic == 1"
766a866c
MM
5049 "{l|lwz} %0,%a1@got(%2)"
5050 [(set_attr "type" "load")])
5051
1fd4e8c1
RK
5052;; For SI, we special-case integers that can't be loaded in one insn. We
5053;; do the load 16-bits at a time. We could do this by loading from memory,
5054;; and this is even supposed to be faster, but it is simpler not to get
5055;; integers in the TOC.
5056(define_expand "movsi"
5057 [(set (match_operand:SI 0 "general_operand" "")
5058 (match_operand:SI 1 "any_operand" ""))]
5059 ""
5060 "
5061{
5062 if (GET_CODE (operands[0]) != REG)
5063 operands[1] = force_reg (SImode, operands[1]);
5064
ef0e171b
RK
5065 /* Convert a move of a CONST_DOUBLE into a CONST_INT */
5066 if (GET_CODE (operands[1]) == CONST_DOUBLE)
5067 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
5068
88228c4b
MM
5069 /* Use default pattern for address of ELF small data */
5070 if (TARGET_ELF
c81bebd7 5071 && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
88228c4b 5072 && (GET_CODE (operands[1]) == SYMBOL_REF || GET_CODE (operands[1]) == CONST)
e98bb982 5073 && small_data_operand (operands[1], SImode))
88228c4b
MM
5074 {
5075 emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
5076 DONE;
5077 }
5078
c81bebd7 5079 if ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
84f414bc 5080 && flag_pic == 1 && got_operand (operands[1], SImode))
766a866c
MM
5081 {
5082 emit_insn (gen_movsi_got (operands[0], operands[1]));
5083 DONE;
5084 }
5085
4697a36c
MM
5086 if (TARGET_ELF && TARGET_NO_TOC && !TARGET_64BIT
5087 && CONSTANT_P (operands[1])
5088 && GET_CODE (operands[1]) != HIGH
5089 && GET_CODE (operands[1]) != CONST_INT)
5090 {
5091 rtx target = (reload_completed || reload_in_progress)
5092 ? operands[0] : gen_reg_rtx (SImode);
5093
b6c9286a
MM
5094 /* If this is a function address on -mcall-aixdesc or -mcall-nt,
5095 convert it to the address of the descriptor. */
5096 if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
5097 && GET_CODE (operands[1]) == SYMBOL_REF
5098 && XSTR (operands[1], 0)[0] == '.')
5099 {
5100 char *name = XSTR (operands[1], 0);
5101 rtx new_ref;
5102 while (*name == '.')
5103 name++;
5104 new_ref = gen_rtx (SYMBOL_REF, Pmode, name);
5105 CONSTANT_POOL_ADDRESS_P (new_ref) = CONSTANT_POOL_ADDRESS_P (operands[1]);
5106 SYMBOL_REF_FLAG (new_ref) = SYMBOL_REF_FLAG (operands[1]);
5107 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
5108 operands[1] = new_ref;
5109 }
5110
4697a36c
MM
5111 emit_insn (gen_elf_high (target, operands[1]));
5112 emit_insn (gen_elf_low (operands[0], target, operands[1]));
5113 DONE;
5114 }
5115
b6c9286a
MM
5116 if (GET_CODE (operands[1]) == CONST
5117 && DEFAULT_ABI == ABI_NT
5118 && !side_effects_p (operands[0]))
5119 {
5120 rtx const_term = const0_rtx;
5121 rtx sym = eliminate_constant_term (XEXP (operands[1], 0), &const_term);
5122 if (sym && GET_CODE (const_term) == CONST_INT
5123 && (GET_CODE (sym) == SYMBOL_REF || GET_CODE (sym) == LABEL_REF))
5124 {
354b734b
MM
5125 unsigned HOST_WIDE_INT value = INTVAL (const_term);
5126 int new_reg_p = (flag_expensive_optimizations
5127 && !reload_completed
5128 && !reload_in_progress);
5129 rtx tmp1 = (new_reg_p && value != 0) ? gen_reg_rtx (SImode) : operands[0];
5130
5131 emit_insn (gen_movsi (tmp1, sym));
b6c9286a
MM
5132 if (INTVAL (const_term) != 0)
5133 {
b6c9286a 5134 if (value + 0x8000 < 0x10000)
354b734b
MM
5135 emit_insn (gen_addsi3 (operands[0], tmp1, GEN_INT (value)));
5136
b6c9286a
MM
5137 else
5138 {
354b734b
MM
5139 HOST_WIDE_INT high_int = value & (~ (HOST_WIDE_INT) 0xffff);
5140 HOST_WIDE_INT low_int = value & 0xffff;
5141 rtx tmp2 = (!new_reg_p || !low_int) ? operands[0] : gen_reg_rtx (Pmode);
5142
5143 if (low_int & 0x8000)
5144 high_int += 0x10000, low_int |= ((HOST_WIDE_INT) -1) << 16;
b6c9286a 5145
354b734b
MM
5146 emit_insn (gen_addsi3 (tmp2, tmp1, GEN_INT (high_int)));
5147 if (low_int)
5148 emit_insn (gen_addsi3 (operands[0], tmp2, GEN_INT (low_int)));
b6c9286a
MM
5149 }
5150 }
5151 DONE;
5152 }
5153 else
5154 fatal_insn (\"bad address\", operands[1]);
5155 }
5156
5157 if ((!TARGET_WINDOWS_NT || DEFAULT_ABI != ABI_NT)
5158 && CONSTANT_P (operands[1])
4697a36c
MM
5159 && GET_CODE (operands[1]) != CONST_INT
5160 && GET_CODE (operands[1]) != HIGH
78b8d850 5161 && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1]))
b45863ec 5162 {
30a4619d
RK
5163 /* If we are to limit the number of things we put in the TOC and
5164 this is a symbol plus a constant we can add in one insn,
abc95ed3 5165 just put the symbol in the TOC and add the constant. Don't do
30a4619d
RK
5166 this if reload is in progress. */
5167 if (GET_CODE (operands[1]) == CONST
5168 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
5169 && GET_CODE (XEXP (operands[1], 0)) == PLUS
5170 && add_operand (XEXP (XEXP (operands[1], 0), 1), SImode)
5171 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
5172 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
5173 && ! side_effects_p (operands[0]))
5174 {
5175 rtx sym = force_const_mem (SImode, XEXP (XEXP (operands[1], 0), 0));
5176 rtx other = XEXP (XEXP (operands[1], 0), 1);
5177
5178 emit_insn (gen_addsi3 (operands[0], force_reg (SImode, sym), other));
5179 DONE;
5180 }
5181
b45863ec
RK
5182 operands[1] = force_const_mem (SImode, operands[1]);
5183 if (! memory_address_p (SImode, XEXP (operands[1], 0))
5184 && ! reload_in_progress)
5185 operands[1] = change_address (operands[1], SImode,
5186 XEXP (operands[1], 0));
5187 }
1fd4e8c1
RK
5188}")
5189
5190(define_insn ""
88228c4b
MM
5191 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,r,r,r,r,r,*q,*c*l,*h")
5192 (match_operand:SI 1 "input_operand" "r,S,T,U,m,r,I,J,n,R,*h,r,r,0"))]
19d5775a
RK
5193 "gpc_reg_operand (operands[0], SImode)
5194 || gpc_reg_operand (operands[1], SImode)"
1fd4e8c1 5195 "@
deb9225a 5196 mr %0,%1
b6c9286a
MM
5197 {l|lwz} %0,[toc]%1(2)
5198 {l|lwz} %0,[toc]%l1(2)
b9442c72 5199 {cal|la} %0,%a1
ca7f5001
RK
5200 {l%U1%X1|lwz%U1%X1} %0,%1
5201 {st%U0%X0|stw%U0%X0} %1,%0
19d5775a 5202 {lil|li} %0,%1
802a0058 5203 {liu|lis} %0,%v1
beaec479 5204 #
57fa6739 5205 {cal|la} %0,%1(%*)
1fd4e8c1 5206 mf%1 %0
5c23c401 5207 mt%0 %1
e76e75bb
RK
5208 mt%0 %1
5209 cror 0,0,0"
b7ff3d82 5210 [(set_attr "type" "*,load,load,*,load,store,*,*,*,*,*,*,mtjmpr,*")
88228c4b 5211 (set_attr "length" "4,4,4,4,4,4,4,4,8,4,4,4,4,4")])
1fd4e8c1 5212
77fa0940
RK
5213;; Split a load of a large constant into the appropriate two-insn
5214;; sequence.
5215
5216(define_split
5217 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5218 (match_operand:SI 1 "const_int_operand" ""))]
5219 "(unsigned) (INTVAL (operands[1]) + 0x8000) >= 0x10000
5220 && (INTVAL (operands[1]) & 0xffff) != 0"
5221 [(set (match_dup 0)
5222 (match_dup 2))
5223 (set (match_dup 0)
5224 (ior:SI (match_dup 0)
5225 (match_dup 3)))]
5226 "
5227{
5228 operands[2] = gen_rtx (CONST_INT, VOIDmode,
5229 INTVAL (operands[1]) & 0xffff0000);
5230 operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0xffff);
5231}")
5232
1fd4e8c1
RK
5233(define_insn ""
5234 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
cd2b37d9 5235 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 5236 (const_int 0)))
cd2b37d9 5237 (set (match_operand:SI 0 "gpc_reg_operand" "=r") (match_dup 1))]
1fd4e8c1 5238 ""
deb9225a 5239 "mr. %0,%1"
1fd4e8c1
RK
5240 [(set_attr "type" "compare")])
5241\f
5242(define_expand "movhi"
5243 [(set (match_operand:HI 0 "general_operand" "")
5244 (match_operand:HI 1 "any_operand" ""))]
5245 ""
5246 "
5247{
5248 if (GET_CODE (operands[0]) != REG)
5249 operands[1] = force_reg (HImode, operands[1]);
5250
5251 if (CONSTANT_P (operands[1]) && GET_CODE (operands[1]) != CONST_INT)
b45863ec
RK
5252 {
5253 operands[1] = force_const_mem (HImode, operands[1]);
5254 if (! memory_address_p (HImode, XEXP (operands[1], 0))
5255 && ! reload_in_progress)
5256 operands[1] = change_address (operands[1], HImode,
5257 XEXP (operands[1], 0));
5258 }
1fd4e8c1
RK
5259}")
5260
5261(define_insn ""
fb81d7ce
RK
5262 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*q,*c*l,*h")
5263 (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,r,0"))]
19d5775a
RK
5264 "gpc_reg_operand (operands[0], HImode)
5265 || gpc_reg_operand (operands[1], HImode)"
1fd4e8c1 5266 "@
deb9225a 5267 mr %0,%1
1fd4e8c1
RK
5268 lhz%U1%X1 %0,%1
5269 sth%U0%X0 %1,%0
19d5775a 5270 {lil|li} %0,%w1
1fd4e8c1 5271 mf%1 %0
e76e75bb 5272 mt%0 %1
fb81d7ce 5273 mt%0 %1
e76e75bb 5274 cror 0,0,0"
b7ff3d82 5275 [(set_attr "type" "*,load,store,*,*,*,mtjmpr,*")])
1fd4e8c1
RK
5276
5277(define_expand "movqi"
5278 [(set (match_operand:QI 0 "general_operand" "")
5279 (match_operand:QI 1 "any_operand" ""))]
5280 ""
5281 "
5282{
5283 if (GET_CODE (operands[0]) != REG)
5284 operands[1] = force_reg (QImode, operands[1]);
5285
5286 if (CONSTANT_P (operands[1]) && GET_CODE (operands[1]) != CONST_INT)
b45863ec
RK
5287 {
5288 operands[1] = force_const_mem (QImode, operands[1]);
5289 if (! memory_address_p (QImode, XEXP (operands[1], 0))
5290 && ! reload_in_progress)
5291 operands[1] = change_address (operands[1], QImode,
5292 XEXP (operands[1], 0));
5293 }
1fd4e8c1
RK
5294}")
5295
5296(define_insn ""
fb81d7ce
RK
5297 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*q,*c*l,*h")
5298 (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,r,0"))]
19d5775a
RK
5299 "gpc_reg_operand (operands[0], QImode)
5300 || gpc_reg_operand (operands[1], QImode)"
1fd4e8c1 5301 "@
deb9225a 5302 mr %0,%1
1fd4e8c1
RK
5303 lbz%U1%X1 %0,%1
5304 stb%U0%X0 %1,%0
19d5775a 5305 {lil|li} %0,%1
1fd4e8c1 5306 mf%1 %0
e76e75bb 5307 mt%0 %1
fb81d7ce 5308 mt%0 %1
e76e75bb 5309 cror 0,0,0"
b7ff3d82 5310 [(set_attr "type" "*,load,store,*,*,*,mtjmpr,*")])
1fd4e8c1
RK
5311\f
5312;; Here is how to move condition codes around. When we store CC data in
5313;; an integer register or memory, we store just the high-order 4 bits.
5314;; This lets us not shift in the most common case of CR0.
5315(define_expand "movcc"
5316 [(set (match_operand:CC 0 "nonimmediate_operand" "")
5317 (match_operand:CC 1 "nonimmediate_operand" ""))]
5318 ""
5319 "")
5320
5321(define_insn ""
5322 [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,y,r,r,r,r,m")
5323 (match_operand:CC 1 "nonimmediate_operand" "y,r,r,x,y,r,m,r"))]
5324 "register_operand (operands[0], CCmode)
5325 || register_operand (operands[1], CCmode)"
5326 "@
5327 mcrf %0,%1
5328 mtcrf 128,%1
ca7f5001 5329 {rlinm|rlwinm} %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;{rlinm|rlwinm} %1,%1,%f0,0xffffffff
1fd4e8c1 5330 mfcr %0
ca7f5001 5331 mfcr %0\;{rlinm|rlwinm} %0,%0,%f1,0xf0000000
deb9225a 5332 mr %0,%1
ca7f5001
RK
5333 {l%U1%X1|lwz%U1%X1} %0,%1
5334 {st%U0%U1|stw%U0%U1} %1,%0"
b7ff3d82 5335 [(set_attr "type" "*,*,*,compare,*,*,load,store")
b19003d8 5336 (set_attr "length" "*,*,12,*,8,*,*,*")])
1fd4e8c1 5337\f
e52e05ca
MM
5338;; For floating-point, we normally deal with the floating-point registers
5339;; unless -msoft-float is used. The sole exception is that parameter passing
5340;; can produce floating-point values in fixed-point registers. Unless the
5341;; value is a simple constant or already in memory, we deal with this by
5342;; allocating memory and copying the value explicitly via that memory location.
1fd4e8c1
RK
5343(define_expand "movsf"
5344 [(set (match_operand:SF 0 "nonimmediate_operand" "")
5345 (match_operand:SF 1 "any_operand" ""))]
5346 ""
5347 "
5348{
5349 /* If we are called from reload, we might be getting a SUBREG of a hard
5350 reg. So expand it. */
5351 if (GET_CODE (operands[0]) == SUBREG
5352 && GET_CODE (SUBREG_REG (operands[0])) == REG
5353 && REGNO (SUBREG_REG (operands[0])) < FIRST_PSEUDO_REGISTER)
5354 operands[0] = alter_subreg (operands[0]);
5355 if (GET_CODE (operands[1]) == SUBREG
5356 && GET_CODE (SUBREG_REG (operands[1])) == REG
5357 && REGNO (SUBREG_REG (operands[1])) < FIRST_PSEUDO_REGISTER)
5358 operands[1] = alter_subreg (operands[1]);
5359
3b7f6cca
MM
5360 if (TARGET_SOFT_FLOAT && GET_CODE (operands[0]) == MEM)
5361 operands[1] = force_reg (SFmode, operands[1]);
5362
5363 else if (TARGET_HARD_FLOAT)
1fd4e8c1 5364 {
e52e05ca 5365 if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 32)
1fd4e8c1 5366 {
e52e05ca
MM
5367 /* If this is a store to memory or another integer register do the
5368 move directly. Otherwise store to a temporary stack slot and
5369 load from there into a floating point register. */
5370
5371 if (GET_CODE (operands[0]) == MEM
5372 || (GET_CODE (operands[0]) == REG
5373 && (REGNO (operands[0]) < 32
5374 || (reload_in_progress
5375 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))))
5376 {
5377 emit_move_insn (operand_subword (operands[0], 0, 0, SFmode),
5378 operand_subword (operands[1], 0, 0, SFmode));
5379 DONE;
5380 }
5381 else
5382 {
5383 rtx stack_slot = assign_stack_temp (SFmode, 4, 0);
5384
5385 emit_move_insn (stack_slot, operands[1]);
5386 emit_move_insn (operands[0], stack_slot);
5387 DONE;
5388 }
f6ba0600 5389 }
1fd4e8c1 5390
e52e05ca 5391 if (GET_CODE (operands[0]) == MEM)
f2974b07 5392 {
e52e05ca
MM
5393 /* If operands[1] is a register, it may have double-precision data
5394 in it, so truncate it to single precision. We need not do
5395 this for POWERPC. */
455350f4
RK
5396 if (! TARGET_POWERPC && TARGET_HARD_FLOAT
5397 && GET_CODE (operands[1]) == REG)
e52e05ca 5398 {
455350f4
RK
5399 rtx newreg
5400 = reload_in_progress ? operands[1] : gen_reg_rtx (SFmode);
5401 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
e52e05ca
MM
5402 operands[1] = newreg;
5403 }
5404
5405 operands[1] = force_reg (SFmode, operands[1]);
f2974b07
RK
5406 }
5407
e52e05ca
MM
5408 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) < 32)
5409 {
5410 if (GET_CODE (operands[1]) == MEM
1fd4e8c1 5411#if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT && ! defined(REAL_IS_NOT_DOUBLE)
e52e05ca 5412 || GET_CODE (operands[1]) == CONST_DOUBLE
1fd4e8c1 5413#endif
e52e05ca
MM
5414 || (GET_CODE (operands[1]) == REG
5415 && (REGNO (operands[1]) < 32
5416 || (reload_in_progress
5417 && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER))))
5418 {
5419 emit_move_insn (operand_subword (operands[0], 0, 0, SFmode),
5420 operand_subword (operands[1], 0, 0, SFmode));
5421 DONE;
5422 }
5423 else
5424 {
5425 rtx stack_slot = assign_stack_temp (SFmode, 4, 0);
5426
5427 emit_move_insn (stack_slot, operands[1]);
5428 emit_move_insn (operands[0], stack_slot);
5429 DONE;
5430 }
f6ba0600 5431 }
1fd4e8c1
RK
5432 }
5433
c4c40373 5434 if (CONSTANT_P (operands[1]) && TARGET_HARD_FLOAT)
1fd4e8c1
RK
5435 {
5436 operands[1] = force_const_mem (SFmode, operands[1]);
5437 if (! memory_address_p (SFmode, XEXP (operands[1], 0))
5438 && ! reload_in_progress)
5439 operands[1] = change_address (operands[1], SFmode,
5440 XEXP (operands[1], 0));
5441 }
5442}")
5443
1fd4e8c1 5444(define_split
cd2b37d9 5445 [(set (match_operand:SF 0 "gpc_reg_operand" "")
c4c40373
MM
5446 (match_operand:SF 1 "const_double_operand" ""))]
5447 "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], SFmode) <= 1 && REGNO (operands[0]) <= 31"
5448 [(set (match_dup 2) (match_dup 3))]
685f3906
DE
5449 "
5450{
5451 long l;
5452 REAL_VALUE_TYPE rv;
5453
5454 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
5455 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
c4c40373
MM
5456
5457 operands[2] = gen_rtx (SUBREG, SImode, operands[0], 0);
5458 operands[3] = GEN_INT(l);
685f3906 5459}")
7e69e155 5460
c4c40373
MM
5461(define_split
5462 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5463 (match_operand:SF 1 "const_double_operand" ""))]
5464 "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], SFmode) == 2 && REGNO (operands[0]) <= 31"
5465 [(set (match_dup 2) (match_dup 3))
5466 (set (match_dup 2) (ior:SI (match_dup 2) (match_dup 4)))]
5467 "
5468{
5469 long l;
5470 REAL_VALUE_TYPE rv;
5471
5472 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
5473 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
5474
5475 operands[2] = gen_rtx (SUBREG, SImode, operands[0], 0);
5476 operands[3] = GEN_INT(l & 0xffff0000);
5477 operands[4] = GEN_INT(l & 0x0000ffff);
5478}")
5479
5480(define_insn "*movsf_hardfloat"
5481 [(set (match_operand:SF 0 "fp_reg_or_mem_operand" "=f,f,m,!r,!r")
5482 (match_operand:SF 1 "input_operand" "f,m,f,G,Fn"))]
d14a6d05
MM
5483 "(gpc_reg_operand (operands[0], SFmode)
5484 || gpc_reg_operand (operands[1], SFmode)) && TARGET_HARD_FLOAT"
1fd4e8c1
RK
5485 "@
5486 fmr %0,%1
5487 lfs%U1%X1 %0,%1
c4c40373
MM
5488 stfs%U0%X0 %1,%0
5489 #
5490 #"
5491 [(set_attr "type" "fp,fpload,fpstore,*,*")
5492 (set_attr "length" "4,4,4,4,8")])
d14a6d05 5493
c4c40373
MM
5494(define_insn "*movsf_softfloat"
5495 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,r")
5496 (match_operand:SF 1 "input_operand" "r,m,r,I,J,R,G,Fn"))]
d14a6d05
MM
5497 "(gpc_reg_operand (operands[0], SFmode)
5498 || gpc_reg_operand (operands[1], SFmode)) && TARGET_SOFT_FLOAT"
5499 "@
5500 mr %0,%1
5501 {l%U1%X1|lwz%U1%X1} %0,%1
5502 {st%U0%X0|stw%U0%X0} %1,%0
5503 {lil|li} %0,%1
802a0058 5504 {liu|lis} %0,%v1
c4c40373
MM
5505 {cal|la} %0,%1(%*)
5506 #
5507 #"
5508 [(set_attr "type" "*,load,store,*,*,*,*,*")
5509 (set_attr "length" "4,4,4,4,4,4,4,8")])
d14a6d05 5510
1fd4e8c1
RK
5511\f
5512(define_expand "movdf"
5513 [(set (match_operand:DF 0 "nonimmediate_operand" "")
5514 (match_operand:DF 1 "any_operand" ""))]
5515 ""
5516 "
5517{
e7113111
RK
5518 if (GET_CODE (operands[0]) != REG)
5519 operands[1] = force_reg (DFmode, operands[1]);
1fd4e8c1 5520
08075ead
DE
5521 /* Stores between FPR and any non-FPR registers must go through a
5522 temporary stack slot. */
5523
5524 if (TARGET_POWERPC64
5525 && GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG
5526 && ((FP_REGNO_P (REGNO (operands[0]))
5527 && ! FP_REGNO_P (REGNO (operands[1])))
5528 || (FP_REGNO_P (REGNO (operands[1]))
5529 && ! FP_REGNO_P (REGNO (operands[0])))))
5530 {
5531 rtx stack_slot = assign_stack_temp (DFmode, 8, 0);
5532
5533 emit_move_insn (stack_slot, operands[1]);
5534 emit_move_insn (operands[0], stack_slot);
5535 DONE;
5536 }
5537
e7113111 5538 if (CONSTANT_P (operands[1]) && ! easy_fp_constant (operands[1], DFmode))
1fd4e8c1
RK
5539 {
5540 operands[1] = force_const_mem (DFmode, operands[1]);
5541 if (! memory_address_p (DFmode, XEXP (operands[1], 0))
5542 && ! reload_in_progress)
5543 operands[1] = change_address (operands[1], DFmode,
5544 XEXP (operands[1], 0));
5545 }
e7113111 5546}")
1fd4e8c1
RK
5547
5548(define_split
cd2b37d9 5549 [(set (match_operand:DF 0 "gpc_reg_operand" "")
c4c40373
MM
5550 (match_operand:DF 1 "const_int_operand" ""))]
5551 "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DFmode) <= 1 && REGNO (operands[0]) <= 31"
5552 [(set (match_dup 2) (match_dup 4))
5553 (set (match_dup 3) (match_dup 1))]
5554 "
5555{
5556 operands[2] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0);
5557 operands[3] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0);
5558 operands[4] = (INTVAL (operands[1]) & 0x80000000) ? constm1_rtx : const0_rtx;
5559}")
5560
5561(define_split
5562 [(set (match_operand:DF 0 "gpc_reg_operand" "")
5563 (match_operand:DF 1 "const_int_operand" ""))]
5564 "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DFmode) >= 2 && REGNO (operands[0]) <= 31"
5565 [(set (match_dup 3) (match_dup 5))
5566 (set (match_dup 2) (match_dup 4))
5567 (set (match_dup 3) (ior:SI (match_dup 3) (match_dup 6)))]
5568 "
5569{
5570 HOST_WIDE_INT value = INTVAL (operands[1]);
5571 operands[2] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0);
5572 operands[3] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0);
5573 operands[4] = (value & 0x80000000) ? constm1_rtx : const0_rtx;
5574 operands[5] = GEN_INT (value & 0xffff0000);
5575 operands[6] = GEN_INT (value & 0x0000ffff);
5576}")
5577
5578(define_split
5579 [(set (match_operand:DF 0 "gpc_reg_operand" "")
5580 (match_operand:DF 1 "const_double_operand" ""))]
5581 "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DFmode) <= 2 && REGNO (operands[0]) <= 31"
5582 [(set (match_dup 2) (match_dup 4))
5583 (set (match_dup 3) (match_dup 5))]
5584 "
5585{
5586 operands[2] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0);
5587 operands[3] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0);
f6968f59
MM
5588
5589#ifdef HOST_WORDS_BIG_ENDIAN
5590 operands[4] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
5591 operands[5] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
5592#else
5593 operands[4] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
5594 operands[5] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
5595#endif
c4c40373
MM
5596}")
5597
5598(define_split
5599 [(set (match_operand:DF 0 "gpc_reg_operand" "")
5600 (match_operand:DF 1 "const_double_operand" ""))]
5601 "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DFmode) == 3 && REGNO (operands[0]) <= 31"
5602 [(set (match_dup 2) (match_dup 4))
5603 (set (match_dup 3) (match_dup 5))
5604 (set (match_dup 2) (ior:SI (match_dup 2) (match_dup 6)))]
5605 "
5606{
a651f222
MM
5607 HOST_WIDE_INT high;
5608 HOST_WIDE_INT low;
c4c40373
MM
5609 rtx high_reg = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0);
5610 rtx low_reg = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0);
5611
f6968f59
MM
5612#ifdef HOST_WORDS_BIG_ENDIAN
5613 high = CONST_DOUBLE_LOW (operands[1]);
5614 low = CONST_DOUBLE_HIGH (operands[1]);
5615#else
5616 high = CONST_DOUBLE_HIGH (operands[1]);
5617 low = CONST_DOUBLE_LOW (operands[1]);
5618#endif
a651f222 5619
c4c40373
MM
5620 if (((unsigned HOST_WIDE_INT) (low + 0x8000) < 0x10000)
5621 || (low & 0xffff) == 0)
5622 {
5623 operands[2] = high_reg;
5624 operands[3] = low_reg;
5625 operands[4] = GEN_INT (high & 0xffff0000);
5626 operands[5] = GEN_INT (low);
5627 operands[6] = GEN_INT (high & 0x0000ffff);
5628 }
5629 else
5630 {
5631 operands[2] = low_reg;
5632 operands[3] = high_reg;
5633 operands[4] = GEN_INT (low & 0xffff0000);
5634 operands[5] = GEN_INT (high);
5635 operands[6] = GEN_INT (low & 0x0000ffff);
5636 }
5637}")
5638
5639(define_split
5640 [(set (match_operand:DF 0 "gpc_reg_operand" "")
5641 (match_operand:DF 1 "const_double_operand" ""))]
5642 "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DFmode) >= 4 && REGNO (operands[0]) <= 31"
5643 [(set (match_dup 2) (match_dup 4))
5644 (set (match_dup 3) (match_dup 5))
5645 (set (match_dup 2) (ior:SI (match_dup 2) (match_dup 6)))
5646 (set (match_dup 3) (ior:SI (match_dup 3) (match_dup 7)))]
1fd4e8c1 5647 "
c4c40373 5648{
f6968f59
MM
5649 HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5650 HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
c4c40373
MM
5651
5652 operands[2] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0);
5653 operands[3] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0);
5654 operands[4] = GEN_INT (high & 0xffff0000);
5655 operands[5] = GEN_INT (low & 0xffff0000);
5656 operands[6] = GEN_INT (high & 0x0000ffff);
5657 operands[7] = GEN_INT (low & 0x0000ffff);
5658}")
e7113111 5659
efc08378
DE
5660(define_split
5661 [(set (match_operand:DF 0 "gpc_reg_operand" "")
685f3906 5662 (match_operand:DF 1 "easy_fp_constant" ""))]
efc08378
DE
5663 "TARGET_64BIT && reload_completed && REGNO (operands[0]) <= 31"
5664 [(set (subreg:DI (match_dup 0) 0) (subreg:DI (match_dup 1) 0))]
5665 "")
5666
4eae5fe1
RK
5667;; Don't have reload use general registers to load a constant. First,
5668;; it might not work if the output operand has is the equivalent of
5669;; a non-offsettable memref, but also it is less efficient than loading
5670;; the constant into an FP register, since it will probably be used there.
5671;; The "??" is a kludge until we can figure out a more reasonable way
5672;; of handling these non-offsettable values.
c4c40373
MM
5673(define_insn "*movdf_hardfloat32"
5674 [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,o,!r,!r,!r,f,f,m")
5675 (match_operand:DF 1 "input_operand" "r,o,r,G,H,F,f,m,f"))]
dc4f83ca
MM
5676 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
5677 && (register_operand (operands[0], DFmode)
5678 || register_operand (operands[1], DFmode))"
e7113111
RK
5679 "*
5680{
5681 switch (which_alternative)
5682 {
5683 case 0:
5684 /* We normally copy the low-numbered register first. However, if
5685 the first register operand 0 is the same as the second register of
5686 operand 1, we must copy in the opposite order. */
5687 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
deb9225a 5688 return \"mr %L0,%L1\;mr %0,%1\";
e7113111 5689 else
deb9225a 5690 return \"mr %0,%1\;mr %L0,%L1\";
e7113111
RK
5691 case 1:
5692 /* If the low-address word is used in the address, we must load it
5693 last. Otherwise, load it first. Note that we cannot have
5694 auto-increment in that case since the address register is known to be
5695 dead. */
5696 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
5697 operands [1], 0))
ca7f5001 5698 return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
e7113111 5699 else
ca7f5001 5700 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
e7113111 5701 case 2:
ca7f5001 5702 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
e7113111 5703 case 3:
e7113111 5704 case 4:
e7113111 5705 case 5:
c4c40373 5706 return \"#\";
e7113111 5707 case 6:
c4c40373
MM
5708 return \"fmr %0,%1\";
5709 case 7:
5710 return \"lfd%U1%X1 %0,%1\";
5711 case 8:
e7113111
RK
5712 return \"stfd%U0%X0 %1,%0\";
5713 }
5714}"
c4c40373
MM
5715 [(set_attr "type" "*,load,store,*,*,*,fp,fpload,fpstore")
5716 (set_attr "length" "8,8,8,8,12,16,*,*,*")])
51b8fc2c 5717
c4c40373
MM
5718(define_insn "*movdf_softfloat32"
5719 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,o,r,r,r")
5720 (match_operand:DF 1 "input_operand" "r,o,r,G,H,F"))]
dc4f83ca
MM
5721 "! TARGET_POWERPC64 && TARGET_SOFT_FLOAT
5722 && (register_operand (operands[0], DFmode)
5723 || register_operand (operands[1], DFmode))"
5724 "*
5725{
5726 switch (which_alternative)
5727 {
5728 case 0:
5729 /* We normally copy the low-numbered register first. However, if
5730 the first register operand 0 is the same as the second register of
5731 operand 1, we must copy in the opposite order. */
5732 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
5733 return \"mr %L0,%L1\;mr %0,%1\";
5734 else
5735 return \"mr %0,%1\;mr %L0,%L1\";
5736 case 1:
5737 /* If the low-address word is used in the address, we must load it
5738 last. Otherwise, load it first. Note that we cannot have
5739 auto-increment in that case since the address register is known to be
5740 dead. */
5741 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
5742 operands [1], 0))
5743 return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
5744 else
5745 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
5746 case 2:
5747 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
5748 case 3:
c4c40373
MM
5749 case 4:
5750 case 5:
dc4f83ca
MM
5751 return \"#\";
5752 }
5753}"
c4c40373
MM
5754 [(set_attr "type" "*,load,store,*,*,*")
5755 (set_attr "length" "8,8,8,8,12,16")])
dc4f83ca 5756
c4c40373
MM
5757(define_insn "*movdf_hardfloat64"
5758 [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,o,!r,!r,!r,f,f,m")
5759 (match_operand:DF 1 "input_operand" "r,o,r,G,H,F,f,m,f"))]
dc4f83ca
MM
5760 "TARGET_POWERPC64 && TARGET_HARD_FLOAT
5761 && (register_operand (operands[0], DFmode)
5762 || register_operand (operands[1], DFmode))"
51b8fc2c 5763 "@
3d5570cb
RK
5764 mr %0,%1
5765 ld%U1%X1 %0,%1
96bb8ed3 5766 std%U0%X0 %1,%0
3d5570cb 5767 #
c4c40373
MM
5768 #
5769 #
3d5570cb 5770 fmr %0,%1
f63184ac 5771 lfd%U1%X1 %0,%1
3d5570cb 5772 stfd%U0%X0 %1,%0"
c4c40373
MM
5773 [(set_attr "type" "*,load,store,*,*,*,fp,fpload,fpstore")
5774 (set_attr "length" "4,4,4,8,12,16,4,4,4")])
dc4f83ca 5775
c4c40373
MM
5776(define_insn "*movdf_softfloat64"
5777 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,o,r,r,r")
5778 (match_operand:DF 1 "input_operand" "r,o,r,G,H,F"))]
dc4f83ca
MM
5779 "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
5780 && (register_operand (operands[0], DFmode)
5781 || register_operand (operands[1], DFmode))"
5782 "@
5783 mr %0,%1
5784 ld%U1%X1 %0,%1
96bb8ed3 5785 std%U0%X0 %1,%0
c4c40373
MM
5786 #
5787 #
dc4f83ca 5788 #"
c4c40373
MM
5789 [(set_attr "type" "*,load,store,*,*,*")
5790 (set_attr "length" "*,*,*,8,12,16")])
1fd4e8c1
RK
5791\f
5792;; Next come the multi-word integer load and store and the load and store
5793;; multiple insns.
5794(define_expand "movdi"
5795 [(set (match_operand:DI 0 "general_operand" "")
e6ca2c17 5796 (match_operand:DI 1 "any_operand" ""))]
1fd4e8c1
RK
5797 ""
5798 "
5799{
e6ca2c17 5800 if (GET_CODE (operands[0]) != REG)
6b6ccd10
RK
5801 operands[1] = force_reg (DImode, operands[1]);
5802
4e74d8ec
MM
5803 if (TARGET_64BIT
5804 && (GET_CODE (operands[1]) == CONST_DOUBLE
5805 || GET_CODE (operands[1]) == CONST_INT))
1fd4e8c1 5806 {
6b6ccd10
RK
5807 HOST_WIDE_INT low;
5808 HOST_WIDE_INT high;
5809
5810 if (GET_CODE (operands[1]) == CONST_DOUBLE)
5811 {
f6968f59
MM
5812 low = CONST_DOUBLE_LOW (operands[1]);
5813 high = CONST_DOUBLE_HIGH (operands[1]);
6b6ccd10 5814 }
e8d791dd
DE
5815 else
5816#if HOST_BITS_PER_WIDE_INT == 32
6b6ccd10
RK
5817 {
5818 low = INTVAL (operands[1]);
5819 high = (low < 0) ? ~0 : 0;
5820 }
e8d791dd 5821#else
e6ca2c17
DE
5822 {
5823 low = INTVAL (operands[1]) & 0xffffffff;
f4558646 5824 high = (HOST_WIDE_INT) INTVAL (operands[1]) >> 32;
e6ca2c17 5825 }
e8d791dd 5826#endif
6b6ccd10 5827
4e74d8ec
MM
5828 if (high)
5829 {
5830 emit_move_insn (operands[0], GEN_INT (high));
5831 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT(32)));
5832 if (low)
5833 {
5834 HOST_WIDE_INT low_low = low & 0xffff;
5835 HOST_WIDE_INT low_high = low & (~ (HOST_WIDE_INT) 0xffff);
5836 if (low_high)
5837 emit_insn (gen_iordi3 (operands[0], operands[0],
5838 GEN_INT (low_high)));
5839 if (low_low)
5840 emit_insn (gen_iordi3 (operands[0], operands[0],
5841 GEN_INT (low_low)));
5842 }
5843 DONE;
5844 }
1fd4e8c1 5845 }
062284d8 5846
a473029f
RK
5847 /* Stores between FPR and any non-FPR registers must go through a
5848 temporary stack slot. */
5849
5850 if (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG
5851 && ((FP_REGNO_P (REGNO (operands[0]))
5852 && ! FP_REGNO_P (REGNO (operands[1])))
5853 || (FP_REGNO_P (REGNO (operands[1]))
5854 && ! FP_REGNO_P (REGNO (operands[0])))))
5855 {
425c176f 5856 rtx stack_slot = assign_stack_temp (DImode, 8, 0);
a473029f 5857
a473029f
RK
5858 emit_move_insn (stack_slot, operands[1]);
5859 emit_move_insn (operands[0], stack_slot);
5860 DONE;
5861 }
1fd4e8c1
RK
5862}")
5863
c4c40373 5864(define_insn "*movdi_32"
4e74d8ec
MM
5865 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,f,f,m,r,r,r,r,r")
5866 (match_operand:DI 1 "input_operand" "r,m,r,f,m,f,IJK,n,G,H,F"))]
5867 "TARGET_32BIT
5868 && (gpc_reg_operand (operands[0], DImode)
5869 || gpc_reg_operand (operands[1], DImode))"
1fd4e8c1
RK
5870 "*
5871{
5872 switch (which_alternative)
5873 {
5874 case 0:
5875 /* We normally copy the low-numbered register first. However, if
5876 the first register operand 0 is the same as the second register of
5877 operand 1, we must copy in the opposite order. */
5878 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
deb9225a 5879 return \"mr %L0,%L1\;mr %0,%1\";
1fd4e8c1 5880 else
deb9225a 5881 return \"mr %0,%1\;mr %L0,%L1\";
1fd4e8c1
RK
5882 case 1:
5883 /* If the low-address word is used in the address, we must load it
5884 last. Otherwise, load it first. Note that we cannot have
5885 auto-increment in that case since the address register is known to be
5886 dead. */
5887 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
5888 operands [1], 0))
ca7f5001 5889 return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
1fd4e8c1 5890 else
ca7f5001 5891 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
1fd4e8c1 5892 case 2:
ca7f5001 5893 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
8ffd9c51
RK
5894 case 3:
5895 return \"fmr %0,%1\";
5896 case 4:
5897 return \"lfd%U1%X1 %0,%1\";
5898 case 5:
5899 return \"stfd%U0%X0 %1,%0\";
4e74d8ec
MM
5900 case 6:
5901 case 7:
5902 case 8:
5903 case 9:
5904 case 10:
5905 return \"#\";
1fd4e8c1
RK
5906 }
5907}"
4e74d8ec
MM
5908 [(set_attr "type" "*,load,store,fp,fpload,fpstore,*,*,*,*,*")
5909 (set_attr "length" "8,8,8,*,*,*,8,12,8,12,16")])
5910
5911(define_split
5912 [(set (match_operand:DI 0 "gpc_reg_operand" "")
5913 (match_operand:DI 1 "const_int_operand" ""))]
5914 "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DImode) <= 1"
5915 [(set (match_dup 2) (match_dup 4))
5916 (set (match_dup 3) (match_dup 1))]
5917 "
5918{
5919 operands[2] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0);
5920 operands[3] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0);
5921 operands[4] = (INTVAL (operands[1]) & 0x80000000) ? constm1_rtx : const0_rtx;
5922}")
5923
5924(define_split
5925 [(set (match_operand:DI 0 "gpc_reg_operand" "")
5926 (match_operand:DI 1 "const_int_operand" ""))]
5927 "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DImode) >= 2"
5928 [(set (match_dup 3) (match_dup 5))
5929 (set (match_dup 2) (match_dup 4))
5930 (set (match_dup 3) (ior:SI (match_dup 3) (match_dup 6)))]
5931 "
5932{
5933 HOST_WIDE_INT value = INTVAL (operands[1]);
5934 operands[2] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0);
5935 operands[3] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0);
5936 operands[4] = (value & 0x80000000) ? constm1_rtx : const0_rtx;
5937 operands[5] = GEN_INT (value & 0xffff0000);
5938 operands[6] = GEN_INT (value & 0x0000ffff);
5939}")
5940
5941(define_split
5942 [(set (match_operand:DI 0 "gpc_reg_operand" "")
5943 (match_operand:DI 1 "const_double_operand" ""))]
5944 "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DImode) <= 2"
5945 [(set (match_dup 2) (match_dup 4))
5946 (set (match_dup 3) (match_dup 5))]
5947 "
5948{
5949 operands[2] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0);
5950 operands[3] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0);
f6968f59
MM
5951 operands[4] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
5952 operands[5] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
4e74d8ec
MM
5953}")
5954
5955(define_split
5956 [(set (match_operand:DI 0 "gpc_reg_operand" "")
5957 (match_operand:DI 1 "const_double_operand" ""))]
5958 "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DImode) == 3"
5959 [(set (match_dup 2) (match_dup 4))
5960 (set (match_dup 3) (match_dup 5))
5961 (set (match_dup 2) (ior:SI (match_dup 2) (match_dup 6)))]
5962 "
5963{
f6968f59
MM
5964 HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5965 HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5966 rtx high_reg = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0);
5967 rtx low_reg = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0);
a651f222 5968
4e74d8ec
MM
5969 if (((unsigned HOST_WIDE_INT) (low + 0x8000) < 0x10000)
5970 || (low & 0xffff) == 0)
5971 {
5972 operands[2] = high_reg;
5973 operands[3] = low_reg;
5974 operands[4] = GEN_INT (high & 0xffff0000);
5975 operands[5] = GEN_INT (low);
5976 operands[6] = GEN_INT (high & 0x0000ffff);
5977 }
5978 else
5979 {
5980 operands[2] = low_reg;
5981 operands[3] = high_reg;
5982 operands[4] = GEN_INT (low & 0xffff0000);
5983 operands[5] = GEN_INT (high);
5984 operands[6] = GEN_INT (low & 0x0000ffff);
5985 }
5986}")
5987
5988(define_split
5989 [(set (match_operand:DI 0 "gpc_reg_operand" "")
5990 (match_operand:DI 1 "const_double_operand" ""))]
5991 "TARGET_32BIT && reload_completed && num_insns_constant (operands[1], DImode) >= 4"
5992 [(set (match_dup 2) (match_dup 4))
5993 (set (match_dup 3) (match_dup 5))
5994 (set (match_dup 2) (ior:SI (match_dup 2) (match_dup 6)))
5995 (set (match_dup 3) (ior:SI (match_dup 3) (match_dup 7)))]
5996 "
5997{
f6968f59
MM
5998 HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5999 HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
4e74d8ec
MM
6000
6001 operands[2] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN == 0);
6002 operands[3] = gen_rtx (SUBREG, SImode, operands[0], WORDS_BIG_ENDIAN != 0);
6003 operands[4] = GEN_INT (high & 0xffff0000);
6004 operands[5] = GEN_INT (low & 0xffff0000);
6005 operands[6] = GEN_INT (high & 0x0000ffff);
6006 operands[7] = GEN_INT (low & 0x0000ffff);
6007}")
51b8fc2c 6008
c4c40373 6009(define_insn "*movdi_64"
e6ca2c17 6010 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,f,f,m,r,*h,*h")
4e74d8ec
MM
6011 (match_operand:DI 1 "input_operand" "r,m,r,I,J,nF,R,f,m,f,*h,r,0"))]
6012 "TARGET_64BIT
6013 && (gpc_reg_operand (operands[0], DImode)
6014 || gpc_reg_operand (operands[1], DImode))"
51b8fc2c 6015 "@
3d5570cb
RK
6016 mr %0,%1
6017 ld%U1%X1 %0,%1
96bb8ed3 6018 std%U0%X0 %1,%0
3d5570cb 6019 li %0,%1
802a0058 6020 lis %0,%v1
e6ca2c17 6021 #
57fa6739 6022 {cal|la} %0,%1(%*)
3d5570cb
RK
6023 fmr %0,%1
6024 lfd%U1%X1 %0,%1
6025 stfd%U0%X0 %1,%0
6026 mf%1 %0
08075ead
DE
6027 mt%0 %1
6028 cror 0,0,0"
b7ff3d82 6029 [(set_attr "type" "*,load,store,*,*,*,*,fp,fpload,fpstore,*,mtjmpr,*")
e6ca2c17
DE
6030 (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4")])
6031
6032;; Split a load of a large constant into the appropriate five-instruction
6033;; sequence. The expansion in movdi tries to perform the minimum number of
6034;; steps, but here we have to handle anything in a constant number of insns.
6035
6036(define_split
6037 [(set (match_operand:DI 0 "gpc_reg_operand" "")
6038 (match_operand:DI 1 "const_double_operand" ""))]
4e74d8ec 6039 "TARGET_64BIT && num_insns_constant (operands[1], DImode) > 1"
e6ca2c17
DE
6040 [(set (match_dup 0)
6041 (match_dup 2))
6042 (set (match_dup 0)
6043 (ior:DI (match_dup 0)
6044 (match_dup 3)))
6045 (set (match_dup 0)
6046 (ashift:DI (match_dup 0)
6047 (const_int 32)))
6048 (set (match_dup 0)
6049 (ior:DI (match_dup 0)
6050 (match_dup 4)))
6051 (set (match_dup 0)
6052 (ior:DI (match_dup 0)
6053 (match_dup 5)))]
6054 "
6055{
6056 HOST_WIDE_INT low;
6057 HOST_WIDE_INT high;
6058
6059 if (GET_CODE (operands[1]) == CONST_DOUBLE)
6060 {
f6968f59
MM
6061 low = CONST_DOUBLE_LOW (operands[1]);
6062 high = CONST_DOUBLE_HIGH (operands[1]);
e6ca2c17 6063 }
e8d791dd
DE
6064 else
6065#if HOST_BITS_PER_WIDE_INT == 32
e6ca2c17
DE
6066 {
6067 low = INTVAL (operands[1]);
6068 high = (low < 0) ? ~0 : 0;
6069 }
e8d791dd 6070#else
e6ca2c17
DE
6071 {
6072 low = INTVAL (operands[1]) & 0xffffffff;
f4558646 6073 high = (HOST_WIDE_INT) INTVAL (operands[1]) >> 32;
e6ca2c17 6074 }
e8d791dd 6075#endif
e6ca2c17
DE
6076
6077 if ((high + 0x8000) < 0x10000
6078 && ((low & 0xffff) == 0 || (low & (~ (HOST_WIDE_INT) 0xffff)) == 0))
6079 FAIL;
6080
6081 operands[2] = GEN_INT (high & (~ (HOST_WIDE_INT) 0xffff));
6082 operands[3] = GEN_INT (high & 0xffff);
6083 operands[4] = GEN_INT (low & (~ (HOST_WIDE_INT) 0xffff));
6084 operands[5] = GEN_INT (low & 0xffff);
6085}")
08075ead
DE
6086
6087(define_insn ""
6088 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
6089 (compare:CC (match_operand:DI 1 "gpc_reg_operand" "r")
6090 (const_int 0)))
6091 (set (match_operand:DI 0 "gpc_reg_operand" "=r") (match_dup 1))]
6092 "TARGET_POWERPC64"
6093 "mr. %0,%1"
6094 [(set_attr "type" "compare")])
1fd4e8c1
RK
6095\f
6096;; TImode is similar, except that we usually want to compute the address into
6097;; a register and use lsi/stsi (the exception is during reload). MQ is also
ca7f5001 6098;; clobbered in stsi for POWER, so we need a SCRATCH for it.
1fd4e8c1
RK
6099(define_expand "movti"
6100 [(parallel [(set (match_operand:TI 0 "general_operand" "")
6101 (match_operand:TI 1 "general_operand" ""))
6102 (clobber (scratch:SI))])]
7e69e155 6103 "TARGET_STRING || TARGET_POWERPC64"
1fd4e8c1
RK
6104 "
6105{
6106 if (GET_CODE (operands[0]) == MEM)
6107 operands[1] = force_reg (TImode, operands[1]);
6108
6109 if (GET_CODE (operands[0]) == MEM
6110 && GET_CODE (XEXP (operands[0], 0)) != REG
6111 && ! reload_in_progress)
6112 operands[0] = change_address (operands[0], TImode,
6113 copy_addr_to_reg (XEXP (operands[0], 0)));
6114
6115 if (GET_CODE (operands[1]) == MEM
6116 && GET_CODE (XEXP (operands[1], 0)) != REG
6117 && ! reload_in_progress)
6118 operands[1] = change_address (operands[1], TImode,
6119 copy_addr_to_reg (XEXP (operands[1], 0)));
6120}")
6121
6122;; We say that MQ is clobbered in the last alternative because the first
6123;; alternative would never get used otherwise since it would need a reload
6124;; while the 2nd alternative would not. We put memory cases first so they
6125;; are preferred. Otherwise, we'd try to reload the output instead of
6126;; giving the SCRATCH mq.
6127(define_insn ""
e1469d0d 6128 [(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,m,????r,????r,????r")
1fd4e8c1
RK
6129 (match_operand:TI 1 "reg_or_mem_operand" "r,r,r,Q,m"))
6130 (clobber (match_scratch:SI 2 "=q,q#X,X,X,X"))]
7e69e155 6131 "TARGET_STRING && TARGET_POWER && ! TARGET_POWERPC64
dc4f83ca 6132 && (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))"
1fd4e8c1
RK
6133 "*
6134{
6135 switch (which_alternative)
6136 {
dc4f83ca
MM
6137 default:
6138 abort ();
6139
1fd4e8c1 6140 case 0:
ca7f5001 6141 return \"{stsi|stswi} %1,%P0,16\";
1fd4e8c1
RK
6142
6143 case 1:
ca7f5001 6144 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\;{st|stw} %Y1,%Y0\;{st|stw} %Z1,%Z0\";
1fd4e8c1
RK
6145
6146 case 2:
6147 /* Normally copy registers with lowest numbered register copied first.
6148 But copy in the other order if the first register of the output
6149 is the second, third, or fourth register in the input. */
6150 if (REGNO (operands[0]) >= REGNO (operands[1]) + 1
6151 && REGNO (operands[0]) <= REGNO (operands[1]) + 3)
deb9225a 6152 return \"mr %Z0,%Z1\;mr %Y0,%Y1\;mr %L0,%L1\;mr %0,%1\";
1fd4e8c1 6153 else
deb9225a 6154 return \"mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1\";
1fd4e8c1
RK
6155 case 3:
6156 /* If the address is not used in the output, we can use lsi. Otherwise,
6157 fall through to generating four loads. */
6158 if (! reg_overlap_mentioned_p (operands[0], operands[1]))
ca7f5001 6159 return \"{lsi|lswi} %0,%P1,16\";
1fd4e8c1
RK
6160 /* ... fall through ... */
6161 case 4:
6162 /* If the address register is the same as the register for the lowest-
6163 addressed word, load it last. Similarly for the next two words.
6164 Otherwise load lowest address to highest. */
6165 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
6166 operands[1], 0))
ca7f5001 6167 return \"{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %0,%1\";
1fd4e8c1
RK
6168 else if (refers_to_regno_p (REGNO (operands[0]) + 1,
6169 REGNO (operands[0]) + 2, operands[1], 0))
ca7f5001 6170 return \"{l|lwz} %0,%1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %L0,%L1\";
1fd4e8c1
RK
6171 else if (refers_to_regno_p (REGNO (operands[0]) + 2,
6172 REGNO (operands[0]) + 3, operands[1], 0))
ca7f5001 6173 return \"{l|lwz} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Z0,%Z1\;{l|lwz} %Y0,%Y1\";
1fd4e8c1 6174 else
ca7f5001 6175 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\";
1fd4e8c1
RK
6176 }
6177}"
b7ff3d82 6178 [(set_attr "type" "store,store,*,load,load")
b19003d8 6179 (set_attr "length" "*,16,16,*,16")])
51b8fc2c 6180
dc4f83ca
MM
6181(define_insn ""
6182 [(set (match_operand:TI 0 "reg_or_mem_operand" "=m,????r,????r")
6183 (match_operand:TI 1 "reg_or_mem_operand" "r,r,m"))
6184 (clobber (match_scratch:SI 2 "=X,X,X"))]
7e69e155 6185 "TARGET_STRING && !TARGET_POWER && ! TARGET_POWERPC64
dc4f83ca
MM
6186 && (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))"
6187 "*
6188{
6189 switch (which_alternative)
6190 {
6191 default:
6192 abort ();
6193
6194 case 0:
6195 return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\;{st|stw} %Y1,%Y0\;{st|stw} %Z1,%Z0\";
6196
6197 case 1:
6198 /* Normally copy registers with lowest numbered register copied first.
6199 But copy in the other order if the first register of the output
6200 is the second, third, or fourth register in the input. */
6201 if (REGNO (operands[0]) >= REGNO (operands[1]) + 1
6202 && REGNO (operands[0]) <= REGNO (operands[1]) + 3)
6203 return \"mr %Z0,%Z1\;mr %Y0,%Y1\;mr %L0,%L1\;mr %0,%1\";
6204 else
6205 return \"mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1\";
6206 case 2:
6207 /* If the address register is the same as the register for the lowest-
6208 addressed word, load it last. Similarly for the next two words.
6209 Otherwise load lowest address to highest. */
6210 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
6211 operands[1], 0))
6212 return \"{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %0,%1\";
6213 else if (refers_to_regno_p (REGNO (operands[0]) + 1,
6214 REGNO (operands[0]) + 2, operands[1], 0))
6215 return \"{l|lwz} %0,%1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %L0,%L1\";
6216 else if (refers_to_regno_p (REGNO (operands[0]) + 2,
6217 REGNO (operands[0]) + 3, operands[1], 0))
6218 return \"{l|lwz} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Z0,%Z1\;{l|lwz} %Y0,%Y1\";
6219 else
6220 return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\";
6221 }
6222}"
b7ff3d82 6223 [(set_attr "type" "store,*,load")
dc4f83ca
MM
6224 (set_attr "length" "16,16,16")])
6225
51b8fc2c
RK
6226(define_insn ""
6227 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m")
6228 (match_operand:TI 1 "input_operand" "r,m,r"))]
6229 "TARGET_POWERPC64 && (gpc_reg_operand (operands[0], TImode)
6230 || gpc_reg_operand (operands[1], TImode))"
6231 "*
6232{
6233 switch (which_alternative)
6234 {
6235 case 0:
6236 /* We normally copy the low-numbered register first. However, if
6237 the first register operand 0 is the same as the second register of
6238 operand 1, we must copy in the opposite order. */
6239 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
6240 return \"mr %L0,%L1\;mr %0,%1\";
6241 else
6242 return \"mr %0,%1\;mr %L0,%L1\";
6243 case 1:
6244 /* If the low-address word is used in the address, we must load it
6245 last. Otherwise, load it first. Note that we cannot have
6246 auto-increment in that case since the address register is known to be
6247 dead. */
6248 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
6249 operands [1], 0))
6250 return \"ld %L0,%L1\;ld %0,%1\";
6251 else
6252 return \"ld%U1 %0,%1\;ld %L0,%L1\";
6253 case 2:
6254 return \"std%U0 %1,%0\;std %L1,%L0\";
6255 }
6256}"
b7ff3d82 6257 [(set_attr "type" "*,load,store")
51b8fc2c 6258 (set_attr "length" "8,8,8")])
1fd4e8c1
RK
6259\f
6260(define_expand "load_multiple"
2f622005
RK
6261 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6262 (match_operand:SI 1 "" ""))
6263 (use (match_operand:SI 2 "" ""))])]
7e69e155 6264 "TARGET_STRING"
1fd4e8c1
RK
6265 "
6266{
6267 int regno;
6268 int count;
6269 rtx from;
6270 int i;
6271
6272 /* Support only loading a constant number of fixed-point registers from
6273 memory and only bother with this if more than two; the machine
6274 doesn't support more than eight. */
6275 if (GET_CODE (operands[2]) != CONST_INT
6276 || INTVAL (operands[2]) <= 2
6277 || INTVAL (operands[2]) > 8
6278 || GET_CODE (operands[1]) != MEM
6279 || GET_CODE (operands[0]) != REG
6280 || REGNO (operands[0]) >= 32)
6281 FAIL;
6282
6283 count = INTVAL (operands[2]);
6284 regno = REGNO (operands[0]);
6285
6286 operands[3] = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (count));
6287 from = force_reg (SImode, XEXP (operands[1], 0));
6288
6289 for (i = 0; i < count; i++)
6290 XVECEXP (operands[3], 0, i)
6291 = gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, regno + i),
6292 gen_rtx (MEM, SImode, plus_constant (from, i * 4)));
6293}")
6294
6295(define_insn ""
6296 [(match_parallel 0 "load_multiple_operation"
cd2b37d9 6297 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
4c99e795 6298 (mem:SI (match_operand:SI 2 "register_operand" "b")))])]
7e69e155 6299 "TARGET_STRING"
1fd4e8c1
RK
6300 "*
6301{
6302 /* We have to handle the case where the pseudo used to contain the address
e82ee4cc
RK
6303 is assigned to one of the output registers. */
6304 int i, j;
6305 int words = XVECLEN (operands[0], 0);
6306 rtx xop[10];
6307
6308 if (XVECLEN (operands[0], 0) == 1)
6309 return \"{l|lwz} %1,0(%2)\";
1fd4e8c1 6310
e82ee4cc 6311 for (i = 0; i < words; i++)
1fd4e8c1
RK
6312 if (refers_to_regno_p (REGNO (operands[1]) + i,
6313 REGNO (operands[1]) + i + 1, operands[2], 0))
6314 {
e82ee4cc
RK
6315 if (i == words-1)
6316 {
6317 xop[0] = operands[1];
6318 xop[1] = operands[2];
6319 xop[2] = GEN_INT (4 * (words-1));
d89ddcfd 6320 output_asm_insn (\"{lsi|lswi} %0,%1,%2\;{l|lwz} %1,%2(%1)\", xop);
e82ee4cc
RK
6321 return \"\";
6322 }
6323 else if (i == 0)
6324 {
6325 xop[0] = operands[1];
6326 xop[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
6327 xop[2] = GEN_INT (4 * (words-1));
6328 output_asm_insn (\"{cal %0,4(%0)|addi %0,%0,4}\;{lsi|lswi} %1,%0,%2\;{l|lwz} %0,-4(%0)\", xop);
6329 return \"\";
6330 }
6331 else
6332 {
6333 for (j = 0; j < words; j++)
6334 if (j != i)
6335 {
6336 xop[0] = gen_rtx (REG, SImode, REGNO (operands[1]) + j);
6337 xop[1] = operands[2];
6338 xop[2] = GEN_INT (j * 4);
6339 output_asm_insn (\"{l|lwz} %0,%2(%1)\", xop);
6340 }
6341 xop[0] = operands[2];
6342 xop[1] = GEN_INT (i * 4);
6343 output_asm_insn (\"{l|lwz} %0,%1(%0)\", xop);
6344 return \"\";
6345 }
1fd4e8c1
RK
6346 }
6347
e82ee4cc 6348 return \"{lsi|lswi} %1,%2,%N0\";
1fd4e8c1 6349}"
b19003d8 6350 [(set_attr "type" "load")
e82ee4cc 6351 (set_attr "length" "32")])
b19003d8 6352
b7ff3d82 6353\f
1fd4e8c1 6354(define_expand "store_multiple"
2f622005
RK
6355 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6356 (match_operand:SI 1 "" ""))
6357 (clobber (scratch:SI))
6358 (use (match_operand:SI 2 "" ""))])]
7e69e155 6359 "TARGET_STRING"
1fd4e8c1
RK
6360 "
6361{
6362 int regno;
6363 int count;
6364 rtx to;
6365 int i;
6366
6367 /* Support only storing a constant number of fixed-point registers to
6368 memory and only bother with this if more than two; the machine
6369 doesn't support more than eight. */
6370 if (GET_CODE (operands[2]) != CONST_INT
6371 || INTVAL (operands[2]) <= 2
6372 || INTVAL (operands[2]) > 8
6373 || GET_CODE (operands[0]) != MEM
6374 || GET_CODE (operands[1]) != REG
6375 || REGNO (operands[1]) >= 32)
6376 FAIL;
6377
6378 count = INTVAL (operands[2]);
6379 regno = REGNO (operands[1]);
6380
6381 operands[3] = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (count + 1));
6382 to = force_reg (SImode, XEXP (operands[0], 0));
6383
6384 XVECEXP (operands[3], 0, 0)
6385 = gen_rtx (SET, VOIDmode, gen_rtx (MEM, SImode, to), operands[1]);
6386 XVECEXP (operands[3], 0, 1) = gen_rtx (CLOBBER, VOIDmode,
6387 gen_rtx (SCRATCH, SImode));
6388
6389 for (i = 1; i < count; i++)
6390 XVECEXP (operands[3], 0, i + 1)
6391 = gen_rtx (SET, VOIDmode,
6392 gen_rtx (MEM, SImode, plus_constant (to, i * 4)),
6393 gen_rtx (REG, SImode, regno + i));
6394}")
6395
6396(define_insn ""
6397 [(match_parallel 0 "store_multiple_operation"
6398 [(set (match_operand:SI 1 "indirect_operand" "=Q")
cd2b37d9 6399 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 6400 (clobber (match_scratch:SI 3 "=q"))])]
7e69e155 6401 "TARGET_STRING && TARGET_POWER"
b7ff3d82
DE
6402 "{stsi|stswi} %2,%P1,%O0"
6403 [(set_attr "type" "store")])
d14a6d05
MM
6404
6405(define_insn ""
6406 [(match_parallel 0 "store_multiple_operation"
4c99e795 6407 [(set (mem:SI (match_operand:SI 1 "register_operand" "b"))
d14a6d05
MM
6408 (match_operand:SI 2 "gpc_reg_operand" "r"))
6409 (clobber (match_scratch:SI 3 "X"))])]
7e69e155 6410 "TARGET_STRING && !TARGET_POWER"
b7ff3d82
DE
6411 "{stsi|stswi} %2,%1,%O0"
6412 [(set_attr "type" "store")])
7e69e155
MM
6413
6414\f
6415;; String/block move insn.
6416;; Argument 0 is the destination
6417;; Argument 1 is the source
6418;; Argument 2 is the length
6419;; Argument 3 is the alignment
6420
6421(define_expand "movstrsi"
b6c9286a
MM
6422 [(parallel [(set (match_operand:BLK 0 "" "")
6423 (match_operand:BLK 1 "" ""))
6424 (use (match_operand:SI 2 "" ""))
6425 (use (match_operand:SI 3 "" ""))])]
7e69e155
MM
6426 ""
6427 "
6428{
6429 if (expand_block_move (operands))
6430 DONE;
6431 else
6432 FAIL;
6433}")
6434
6435;; Move up to 32 bytes at a time. The fixed registers are needed because the
6436;; register allocator doesn't have a clue about allocating 8 word registers
6437(define_expand "movstrsi_8reg"
b6c9286a
MM
6438 [(parallel [(set (match_operand 0 "" "")
6439 (match_operand 1 "" ""))
6440 (use (match_operand 2 "" ""))
6441 (use (match_operand 3 "" ""))
7e69e155
MM
6442 (clobber (reg:SI 5))
6443 (clobber (reg:SI 6))
6444 (clobber (reg:SI 7))
6445 (clobber (reg:SI 8))
6446 (clobber (reg:SI 9))
6447 (clobber (reg:SI 10))
6448 (clobber (reg:SI 11))
6449 (clobber (reg:SI 12))
3c67b673 6450 (clobber (match_scratch:SI 4 ""))])]
7e69e155
MM
6451 "TARGET_STRING"
6452 "")
6453
6454(define_insn ""
3c67b673
RK
6455 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6456 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6457 (use (match_operand:SI 2 "immediate_operand" "i"))
6458 (use (match_operand:SI 3 "immediate_operand" "i"))
6459 (clobber (match_operand:SI 4 "register_operand" "=r"))
7e69e155
MM
6460 (clobber (reg:SI 6))
6461 (clobber (reg:SI 7))
6462 (clobber (reg:SI 8))
6463 (clobber (reg:SI 9))
6464 (clobber (reg:SI 10))
6465 (clobber (reg:SI 11))
6466 (clobber (reg:SI 12))
3c67b673 6467 (clobber (match_scratch:SI 5 "=q"))]
7e69e155
MM
6468 "TARGET_STRING && TARGET_POWER
6469 && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32) || INTVAL (operands[2]) == 0)
6470 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
6471 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
3c67b673
RK
6472 && REGNO (operands[4]) == 5"
6473 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
b7ff3d82
DE
6474 [(set_attr "type" "load")
6475 (set_attr "length" "8")])
7e69e155
MM
6476
6477(define_insn ""
3c67b673
RK
6478 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6479 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6480 (use (match_operand:SI 2 "immediate_operand" "i"))
6481 (use (match_operand:SI 3 "immediate_operand" "i"))
6482 (clobber (match_operand:SI 4 "register_operand" "=r"))
7e69e155
MM
6483 (clobber (reg:SI 6))
6484 (clobber (reg:SI 7))
6485 (clobber (reg:SI 8))
6486 (clobber (reg:SI 9))
6487 (clobber (reg:SI 10))
6488 (clobber (reg:SI 11))
6489 (clobber (reg:SI 12))
3c67b673 6490 (clobber (match_scratch:SI 5 "X"))]
7e69e155
MM
6491 "TARGET_STRING && !TARGET_POWER
6492 && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32) || INTVAL (operands[2]) == 0)
6493 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
6494 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
3c67b673
RK
6495 && REGNO (operands[4]) == 5"
6496 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
b7ff3d82
DE
6497 [(set_attr "type" "load")
6498 (set_attr "length" "8")])
7e69e155
MM
6499
6500;; Move up to 24 bytes at a time. The fixed registers are needed because the
6501;; register allocator doesn't have a clue about allocating 6 word registers
6502(define_expand "movstrsi_6reg"
b6c9286a
MM
6503 [(parallel [(set (match_operand 0 "" "")
6504 (match_operand 1 "" ""))
6505 (use (match_operand 2 "" ""))
6506 (use (match_operand 3 "" ""))
7e69e155
MM
6507 (clobber (reg:SI 7))
6508 (clobber (reg:SI 8))
6509 (clobber (reg:SI 9))
6510 (clobber (reg:SI 10))
6511 (clobber (reg:SI 11))
6512 (clobber (reg:SI 12))
3c67b673 6513 (clobber (match_scratch:SI 4 ""))])]
7e69e155
MM
6514 "TARGET_STRING"
6515 "")
6516
6517(define_insn ""
3c67b673
RK
6518 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6519 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6520 (use (match_operand:SI 2 "immediate_operand" "i"))
6521 (use (match_operand:SI 3 "immediate_operand" "i"))
6522 (clobber (match_operand:SI 4 "register_operand" "=r"))
7e69e155
MM
6523 (clobber (reg:SI 8))
6524 (clobber (reg:SI 9))
6525 (clobber (reg:SI 10))
6526 (clobber (reg:SI 11))
6527 (clobber (reg:SI 12))
3c67b673 6528 (clobber (match_scratch:SI 5 "=q"))]
7e69e155
MM
6529 "TARGET_STRING && TARGET_POWER
6530 && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24
6531 && (REGNO (operands[0]) < 7 || REGNO (operands[0]) > 12)
6532 && (REGNO (operands[1]) < 7 || REGNO (operands[1]) > 12)
3c67b673
RK
6533 && REGNO (operands[4]) == 7"
6534 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
b7ff3d82
DE
6535 [(set_attr "type" "load")
6536 (set_attr "length" "8")])
7e69e155
MM
6537
6538(define_insn ""
3c67b673
RK
6539 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6540 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6541 (use (match_operand:SI 2 "immediate_operand" "i"))
6542 (use (match_operand:SI 3 "immediate_operand" "i"))
6543 (clobber (match_operand:SI 4 "register_operand" "=r"))
7e69e155
MM
6544 (clobber (reg:SI 8))
6545 (clobber (reg:SI 9))
6546 (clobber (reg:SI 10))
6547 (clobber (reg:SI 11))
6548 (clobber (reg:SI 12))
3c67b673 6549 (clobber (match_scratch:SI 5 "X"))]
7e69e155
MM
6550 "TARGET_STRING && !TARGET_POWER
6551 && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
6552 && (REGNO (operands[0]) < 7 || REGNO (operands[0]) > 12)
6553 && (REGNO (operands[1]) < 7 || REGNO (operands[1]) > 12)
3c67b673
RK
6554 && REGNO (operands[4]) == 7"
6555 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
b7ff3d82
DE
6556 [(set_attr "type" "load")
6557 (set_attr "length" "8")])
7e69e155
MM
6558
6559;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill problems
6560;; with TImode
6561(define_expand "movstrsi_4reg"
b6c9286a
MM
6562 [(parallel [(set (match_operand 0 "" "")
6563 (match_operand 1 "" ""))
6564 (use (match_operand 2 "" ""))
6565 (use (match_operand 3 "" ""))
7e69e155
MM
6566 (clobber (reg:SI 9))
6567 (clobber (reg:SI 10))
6568 (clobber (reg:SI 11))
6569 (clobber (reg:SI 12))
3c67b673 6570 (clobber (match_scratch:SI 4 ""))])]
7e69e155
MM
6571 "TARGET_STRING"
6572 "")
6573
6574(define_insn ""
3c67b673
RK
6575 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6576 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6577 (use (match_operand:SI 2 "immediate_operand" "i"))
6578 (use (match_operand:SI 3 "immediate_operand" "i"))
6579 (clobber (match_operand:SI 4 "register_operand" "=r"))
7e69e155
MM
6580 (clobber (reg:SI 10))
6581 (clobber (reg:SI 11))
6582 (clobber (reg:SI 12))
3c67b673 6583 (clobber (match_scratch:SI 5 "=q"))]
7e69e155
MM
6584 "TARGET_STRING && TARGET_POWER
6585 && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
6586 && (REGNO (operands[0]) < 9 || REGNO (operands[0]) > 12)
6587 && (REGNO (operands[1]) < 9 || REGNO (operands[1]) > 12)
3c67b673
RK
6588 && REGNO (operands[4]) == 9"
6589 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
b7ff3d82
DE
6590 [(set_attr "type" "load")
6591 (set_attr "length" "8")])
7e69e155
MM
6592
6593(define_insn ""
3c67b673
RK
6594 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6595 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6596 (use (match_operand:SI 2 "immediate_operand" "i"))
6597 (use (match_operand:SI 3 "immediate_operand" "i"))
6598 (clobber (match_operand:SI 4 "register_operand" "=r"))
7e69e155
MM
6599 (clobber (reg:SI 10))
6600 (clobber (reg:SI 11))
6601 (clobber (reg:SI 12))
3c67b673 6602 (clobber (match_scratch:SI 5 "X"))]
7e69e155
MM
6603 "TARGET_STRING && !TARGET_POWER
6604 && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
6605 && (REGNO (operands[0]) < 9 || REGNO (operands[0]) > 12)
6606 && (REGNO (operands[1]) < 9 || REGNO (operands[1]) > 12)
3c67b673
RK
6607 && REGNO (operands[4]) == 9"
6608 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
b7ff3d82
DE
6609 [(set_attr "type" "load")
6610 (set_attr "length" "8")])
7e69e155
MM
6611
6612;; Move up to 8 bytes at a time.
6613(define_expand "movstrsi_2reg"
b6c9286a
MM
6614 [(parallel [(set (match_operand 0 "" "")
6615 (match_operand 1 "" ""))
6616 (use (match_operand 2 "" ""))
6617 (use (match_operand 3 "" ""))
3c67b673
RK
6618 (clobber (match_scratch:DI 4 ""))
6619 (clobber (match_scratch:SI 5 ""))])]
7e69e155
MM
6620 "TARGET_STRING && !TARGET_64BIT"
6621 "")
6622
6623(define_insn ""
3c67b673
RK
6624 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6625 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6626 (use (match_operand:SI 2 "immediate_operand" "i"))
6627 (use (match_operand:SI 3 "immediate_operand" "i"))
6628 (clobber (match_scratch:DI 4 "=&r"))
6629 (clobber (match_scratch:SI 5 "=q"))]
7e69e155 6630 "TARGET_STRING && TARGET_POWER && !TARGET_64BIT
3c67b673
RK
6631 && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
6632 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
b7ff3d82
DE
6633 [(set_attr "type" "load")
6634 (set_attr "length" "8")])
7e69e155
MM
6635
6636(define_insn ""
3c67b673
RK
6637 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6638 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6639 (use (match_operand:SI 2 "immediate_operand" "i"))
6640 (use (match_operand:SI 3 "immediate_operand" "i"))
6641 (clobber (match_scratch:DI 4 "=&r"))
6642 (clobber (match_scratch:SI 5 "X"))]
7e69e155
MM
6643 "TARGET_STRING && !TARGET_POWER && !TARGET_64BIT
6644 && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
3c67b673 6645 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
b7ff3d82
DE
6646 [(set_attr "type" "load")
6647 (set_attr "length" "8")])
7e69e155
MM
6648
6649;; Move up to 4 bytes at a time.
6650(define_expand "movstrsi_1reg"
b6c9286a
MM
6651 [(parallel [(set (match_operand 0 "" "")
6652 (match_operand 1 "" ""))
6653 (use (match_operand 2 "" ""))
6654 (use (match_operand 3 "" ""))
3c67b673
RK
6655 (clobber (match_scratch:SI 4 ""))
6656 (clobber (match_scratch:SI 5 ""))])]
7e69e155
MM
6657 "TARGET_STRING"
6658 "")
6659
6660(define_insn ""
3c67b673
RK
6661 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6662 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6663 (use (match_operand:SI 2 "immediate_operand" "i"))
6664 (use (match_operand:SI 3 "immediate_operand" "i"))
6665 (clobber (match_scratch:SI 4 "=&r"))
6666 (clobber (match_scratch:SI 5 "=q"))]
7e69e155
MM
6667 "TARGET_STRING && TARGET_POWER
6668 && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
3c67b673 6669 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
b7ff3d82
DE
6670 [(set_attr "type" "load")
6671 (set_attr "length" "8")])
7e69e155
MM
6672
6673(define_insn ""
3c67b673
RK
6674 [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
6675 (mem:BLK (match_operand:SI 1 "register_operand" "b")))
6676 (use (match_operand:SI 2 "immediate_operand" "i"))
6677 (use (match_operand:SI 3 "immediate_operand" "i"))
6678 (clobber (match_scratch:SI 4 "=&r"))
6679 (clobber (match_scratch:SI 5 "X"))]
7e69e155
MM
6680 "TARGET_STRING && !TARGET_POWER
6681 && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
3c67b673 6682 "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
b7ff3d82
DE
6683 [(set_attr "type" "load")
6684 (set_attr "length" "8")])
7e69e155 6685
1fd4e8c1 6686\f
7e69e155 6687;; Define insns that do load or store with update. Some of these we can
1fd4e8c1
RK
6688;; get by using pre-decrement or pre-increment, but the hardware can also
6689;; do cases where the increment is not the size of the object.
6690;;
6691;; In all these cases, we use operands 0 and 1 for the register being
6692;; incremented because those are the operands that local-alloc will
6693;; tie and these are the pair most likely to be tieable (and the ones
6694;; that will benefit the most).
6695
51b8fc2c
RK
6696(define_insn ""
6697 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
ad8bd902 6698 (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
51b8fc2c
RK
6699 (match_operand:DI 2 "reg_or_short_operand" "r,I"))))
6700 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
6701 (plus:DI (match_dup 1) (match_dup 2)))]
6702 "TARGET_POWERPC64"
6703 "@
6704 ldux %3,%0,%2
6705 ldu %3,%2(%0)"
6706 [(set_attr "type" "load")])
6707
287f13ff
RK
6708(define_insn ""
6709 [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
6710 (sign_extend:DI
6711 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
6712 (match_operand:DI 2 "gpc_reg_operand" "r")))))
6713 (set (match_operand:DI 0 "gpc_reg_operand" "=b")
6714 (plus:DI (match_dup 1) (match_dup 2)))]
6715 "TARGET_POWERPC64"
6716 "lwaux %3,%0,%2"
6717 [(set_attr "type" "load")])
6718
4697a36c 6719(define_insn "movdi_update"
51b8fc2c
RK
6720 [(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
6721 (match_operand:DI 2 "reg_or_short_operand" "r,I")))
6722 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
6723 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
6724 (plus:DI (match_dup 1) (match_dup 2)))]
6725 "TARGET_POWERPC64"
6726 "@
6727 stdux %3,%0,%2
b7ff3d82
DE
6728 stdu %3,%2(%0)"
6729 [(set_attr "type" "store")])
51b8fc2c 6730
1fd4e8c1 6731(define_insn ""
cd2b37d9
RK
6732 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
6733 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6734 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
cd2b37d9 6735 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
6736 (plus:SI (match_dup 1) (match_dup 2)))]
6737 ""
6738 "@
ca7f5001
RK
6739 {lux|lwzux} %3,%0,%2
6740 {lu|lwzu} %3,%2(%0)"
cfb557c4 6741 [(set_attr "type" "load")])
1fd4e8c1 6742
4697a36c 6743(define_insn "movsi_update"
cd2b37d9 6744 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6745 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
cd2b37d9
RK
6746 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
6747 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
6748 (plus:SI (match_dup 1) (match_dup 2)))]
6749 ""
6750 "@
ca7f5001 6751 {stux|stwux} %3,%0,%2
b7ff3d82
DE
6752 {stu|stwu} %3,%2(%0)"
6753 [(set_attr "type" "store")])
1fd4e8c1
RK
6754
6755(define_insn ""
cd2b37d9
RK
6756 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
6757 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6758 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
cd2b37d9 6759 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
6760 (plus:SI (match_dup 1) (match_dup 2)))]
6761 ""
6762 "@
5f243543
RK
6763 lhzux %3,%0,%2
6764 lhzu %3,%2(%0)"
cfb557c4 6765 [(set_attr "type" "load")])
1fd4e8c1
RK
6766
6767(define_insn ""
cd2b37d9 6768 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
1fd4e8c1 6769 (zero_extend:SI
cd2b37d9 6770 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6771 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
cd2b37d9 6772 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
6773 (plus:SI (match_dup 1) (match_dup 2)))]
6774 ""
6775 "@
5f243543
RK
6776 lhzux %3,%0,%2
6777 lhzu %3,%2(%0)"
cfb557c4 6778 [(set_attr "type" "load")])
1fd4e8c1
RK
6779
6780(define_insn ""
cd2b37d9 6781 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
1fd4e8c1 6782 (sign_extend:SI
cd2b37d9 6783 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6784 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
cd2b37d9 6785 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
6786 (plus:SI (match_dup 1) (match_dup 2)))]
6787 ""
6788 "@
5f243543
RK
6789 lhaux %3,%0,%2
6790 lhau %3,%2(%0)"
cfb557c4 6791 [(set_attr "type" "load")])
1fd4e8c1
RK
6792
6793(define_insn ""
cd2b37d9 6794 [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6795 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
cd2b37d9
RK
6796 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
6797 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
6798 (plus:SI (match_dup 1) (match_dup 2)))]
6799 ""
6800 "@
5f243543 6801 sthux %3,%0,%2
b7ff3d82
DE
6802 sthu %3,%2(%0)"
6803 [(set_attr "type" "store")])
1fd4e8c1
RK
6804
6805(define_insn ""
cd2b37d9
RK
6806 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
6807 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6808 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
cd2b37d9 6809 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
6810 (plus:SI (match_dup 1) (match_dup 2)))]
6811 ""
6812 "@
5f243543
RK
6813 lbzux %3,%0,%2
6814 lbzu %3,%2(%0)"
cfb557c4 6815 [(set_attr "type" "load")])
1fd4e8c1
RK
6816
6817(define_insn ""
cd2b37d9 6818 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
1fd4e8c1 6819 (zero_extend:SI
cd2b37d9 6820 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6821 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
cd2b37d9 6822 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
6823 (plus:SI (match_dup 1) (match_dup 2)))]
6824 ""
6825 "@
5f243543
RK
6826 lbzux %3,%0,%2
6827 lbzu %3,%2(%0)"
cfb557c4 6828 [(set_attr "type" "load")])
1fd4e8c1
RK
6829
6830(define_insn ""
cd2b37d9 6831 [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6832 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
cd2b37d9
RK
6833 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
6834 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1
RK
6835 (plus:SI (match_dup 1) (match_dup 2)))]
6836 ""
6837 "@
5f243543 6838 stbux %3,%0,%2
b7ff3d82
DE
6839 stbu %3,%2(%0)"
6840 [(set_attr "type" "store")])
1fd4e8c1
RK
6841
6842(define_insn ""
cd2b37d9 6843 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
df8b713c 6844 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6845 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
cd2b37d9 6846 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1 6847 (plus:SI (match_dup 1) (match_dup 2)))]
d14a6d05 6848 "TARGET_HARD_FLOAT"
1fd4e8c1 6849 "@
5f243543
RK
6850 lfsux %3,%0,%2
6851 lfsu %3,%2(%0)"
cfb557c4 6852 [(set_attr "type" "fpload")])
1fd4e8c1
RK
6853
6854(define_insn ""
cd2b37d9 6855 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6856 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
cd2b37d9
RK
6857 (match_operand:SF 3 "gpc_reg_operand" "f,f"))
6858 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1 6859 (plus:SI (match_dup 1) (match_dup 2)))]
d14a6d05 6860 "TARGET_HARD_FLOAT"
1fd4e8c1 6861 "@
85fff2f3 6862 stfsux %3,%0,%2
b7ff3d82
DE
6863 stfsu %3,%2(%0)"
6864 [(set_attr "type" "fpstore")])
1fd4e8c1
RK
6865
6866(define_insn ""
cd2b37d9
RK
6867 [(set (match_operand:DF 3 "gpc_reg_operand" "=f,f")
6868 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6869 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
cd2b37d9 6870 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1 6871 (plus:SI (match_dup 1) (match_dup 2)))]
d14a6d05 6872 "TARGET_HARD_FLOAT"
1fd4e8c1 6873 "@
5f243543
RK
6874 lfdux %3,%0,%2
6875 lfdu %3,%2(%0)"
cfb557c4 6876 [(set_attr "type" "fpload")])
1fd4e8c1
RK
6877
6878(define_insn ""
cd2b37d9 6879 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
1fd4e8c1 6880 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
cd2b37d9
RK
6881 (match_operand:DF 3 "gpc_reg_operand" "f,f"))
6882 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
1fd4e8c1 6883 (plus:SI (match_dup 1) (match_dup 2)))]
d14a6d05 6884 "TARGET_HARD_FLOAT"
1fd4e8c1 6885 "@
5f243543 6886 stfdux %3,%0,%2
b7ff3d82
DE
6887 stfdu %3,%2(%0)"
6888 [(set_attr "type" "fpstore")])
4c70a4f3
RK
6889
6890;; Peephole to convert two consecutive FP loads or stores into lfq/stfq.
6891
6892(define_peephole
6893 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
6894 (match_operand:DF 1 "memory_operand" ""))
6895 (set (match_operand:DF 2 "gpc_reg_operand" "=f")
6896 (match_operand:DF 3 "memory_operand" ""))]
6897 "TARGET_POWER2
d14a6d05 6898 && TARGET_HARD_FLOAT
4c70a4f3
RK
6899 && registers_ok_for_quad_peep (operands[0], operands[2])
6900 && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
6901 && addrs_ok_for_quad_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
6902 "lfq%U1%X1 %0,%1")
6903
6904(define_peephole
6905 [(set (match_operand:DF 0 "memory_operand" "")
6906 (match_operand:DF 1 "gpc_reg_operand" "f"))
6907 (set (match_operand:DF 2 "memory_operand" "")
6908 (match_operand:DF 3 "gpc_reg_operand" "f"))]
6909 "TARGET_POWER2
d14a6d05 6910 && TARGET_HARD_FLOAT
4c70a4f3
RK
6911 && registers_ok_for_quad_peep (operands[1], operands[3])
6912 && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
6913 && addrs_ok_for_quad_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
6914 "stfq%U0%X0 %1,%0")
1fd4e8c1
RK
6915\f
6916;; Next come insns related to the calling sequence.
6917;;
6918;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
7e69e155 6919;; We move the back-chain and decrement the stack pointer.
1fd4e8c1
RK
6920
6921(define_expand "allocate_stack"
6922 [(set (reg:SI 1)
01def764 6923 (minus:SI (reg:SI 1) (match_operand:SI 0 "reg_or_short_operand" "")))]
1fd4e8c1
RK
6924 ""
6925 "
4697a36c 6926{ rtx chain = gen_reg_rtx (Pmode);
1fd4e8c1 6927 rtx stack_bot = gen_rtx (MEM, Pmode, stack_pointer_rtx);
4697a36c 6928 rtx neg_op0;
1fd4e8c1
RK
6929
6930 emit_move_insn (chain, stack_bot);
4697a36c 6931
979721f8
MM
6932 /* Under Windows NT, we need to add stack probes for large/variable allocations,
6933 so do it via a call to the external function alloca, instead of doing it
6934 inline. */
6935 if (DEFAULT_ABI == ABI_NT
6936 && (GET_CODE (operands[0]) != CONST_INT || INTVAL (operands[0]) > 4096))
6937 {
cea05fab
MM
6938 rtx tmp = gen_reg_rtx (SImode);
6939 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"__allocate_stack\"),
6940 tmp, 0, SImode, 1, operands[0], Pmode);
6941 emit_insn (gen_set_sp (tmp));
979721f8
MM
6942 DONE;
6943 }
6944
4697a36c
MM
6945 if (GET_CODE (operands[0]) != CONST_INT
6946 || INTVAL (operands[0]) < -32767
6947 || INTVAL (operands[0]) > 32768)
6948 {
6949 neg_op0 = gen_reg_rtx (Pmode);
e6ca2c17 6950 if (TARGET_32BIT)
4697a36c 6951 emit_insn (gen_negsi2 (neg_op0, operands[0]));
e6ca2c17
DE
6952 else
6953 emit_insn (gen_negdi2 (neg_op0, operands[0]));
4697a36c
MM
6954 }
6955 else
6956 neg_op0 = GEN_INT (- INTVAL (operands[0]));
6957
e6ca2c17 6958 if (TARGET_32BIT)
4697a36c 6959 emit_insn (gen_movsi_update (stack_pointer_rtx, stack_pointer_rtx, neg_op0, chain));
e6ca2c17
DE
6960 else
6961 emit_insn (gen_movdi_update (stack_pointer_rtx, stack_pointer_rtx, neg_op0, chain));
4697a36c 6962
1fd4e8c1
RK
6963 DONE;
6964}")
59257ff7 6965
cea05fab
MM
6966;; Marker to indicate that the stack pointer was changed under NT in
6967;; ways not known to the compiler
6968
6969(define_insn "set_sp"
6970 [(set (reg:SI 1)
6971 (unspec [(match_operand:SI 0 "register_operand" "r")] 7))]
6972 ""
6973 ""
6974 [(set_attr "length" "0")])
6975
59257ff7
RK
6976;; These patterns say how to save and restore the stack pointer. We need not
6977;; save the stack pointer at function level since we are careful to
6978;; preserve the backchain. At block level, we have to restore the backchain
6979;; when we restore the stack pointer.
6980;;
6981;; For nonlocal gotos, we must save both the stack pointer and its
6982;; backchain and restore both. Note that in the nonlocal case, the
6983;; save area is a memory location.
6984
6985(define_expand "save_stack_function"
6986 [(use (const_int 0))]
6987 ""
6988 "")
6989
6990(define_expand "restore_stack_function"
6991 [(use (const_int 0))]
6992 ""
6993 "")
6994
6995(define_expand "restore_stack_block"
6996 [(set (match_dup 2) (mem:SI (match_operand:SI 0 "register_operand" "")))
6997 (set (match_dup 0) (match_operand:SI 1 "register_operand" ""))
6998 (set (mem:SI (match_dup 0)) (match_dup 2))]
6999 ""
7000 "
7001{ operands[2] = gen_reg_rtx (SImode); }")
7002
7003(define_expand "save_stack_nonlocal"
7004 [(match_operand:DI 0 "memory_operand" "")
7005 (match_operand:SI 1 "register_operand" "")]
7006 ""
7007 "
7008{
7009 rtx temp = gen_reg_rtx (SImode);
7010
7011 /* Copy the backchain to the first word, sp to the second. */
7012 emit_move_insn (temp, gen_rtx (MEM, SImode, operands[1]));
7013 emit_move_insn (operand_subword (operands[0], 0, 0, DImode), temp);
7014 emit_move_insn (operand_subword (operands[0], 1, 0, DImode), operands[1]);
7015 DONE;
7016}")
7e69e155 7017
59257ff7
RK
7018(define_expand "restore_stack_nonlocal"
7019 [(match_operand:SI 0 "register_operand" "")
7020 (match_operand:DI 1 "memory_operand" "")]
7021 ""
7022 "
7023{
7024 rtx temp = gen_reg_rtx (SImode);
7025
7026 /* Restore the backchain from the first word, sp from the second. */
7027 emit_move_insn (temp, operand_subword (operands[1], 0, 0, DImode));
7028 emit_move_insn (operands[0], operand_subword (operands[1], 1, 0, DImode));
7029 emit_move_insn (gen_rtx (MEM, SImode, operands[0]), temp);
7030 DONE;
7031}")
b6c9286a 7032
b7ff3d82 7033\f
b6c9286a
MM
7034;; A function pointer under AIX is a pointer to a data area whose first word
7035;; contains the actual address of the function, whose second word contains a
7036;; pointer to its TOC, and whose third word contains a value to place in the
7037;; static chain register (r11). Note that if we load the static chain, our
1fd4e8c1
RK
7038;; "trampoline" need not have any executable code.
7039;;
b6c9286a
MM
7040;; operands[0] is a register pointing to the 3 word descriptor (aka, the function address)
7041;; operands[1] is the stack size to clean up
7042;; operands[2] is the value FUNCTION_ARG returns for the VOID argument (must be 0 for AIX)
7043;; operands[3] is location to store the TOC
7044;; operands[4] is the TOC register
7045;; operands[5] is the static chain register
7046;;
7047;; We do not break this into separate insns, so that the scheduler will not try
7048;; to move the load of the new TOC before any loads from the TOC.
7049
7050(define_insn "call_indirect_aix"
7051 [(call (mem:SI (match_operand:SI 0 "register_operand" "b"))
7052 (match_operand 1 "const_int_operand" "n"))
6a4cee5f 7053 (use (match_operand 2 "const_int_operand" "n"))
b6c9286a
MM
7054 (use (match_operand 3 "offsettable_addr_operand" "p"))
7055 (use (match_operand 4 "register_operand" "r"))
7056 (clobber (match_operand 5 "register_operand" "=r"))
7057 (clobber (match_scratch:SI 6 "=&r"))
7058 (clobber (match_scratch:SI 7 "=l"))]
6a4cee5f
MM
7059 "DEFAULT_ABI == ABI_AIX
7060 && (INTVAL (operands[2]) == CALL_NORMAL || (INTVAL (operands[2]) & CALL_LONG) != 0)"
7061 "{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
7062 [(set_attr "type" "load")
7063 (set_attr "length" "28")])
b6c9286a
MM
7064
7065(define_insn "call_value_indirect_aix"
7066 [(set (match_operand 0 "register_operand" "fg")
7067 (call (mem:SI (match_operand:SI 1 "register_operand" "b"))
7068 (match_operand 2 "const_int_operand" "n")))
6a4cee5f 7069 (use (match_operand 3 "const_int_operand" "n"))
b6c9286a
MM
7070 (use (match_operand 4 "offsettable_addr_operand" "p"))
7071 (use (match_operand 5 "register_operand" "r"))
7072 (clobber (match_operand 6 "register_operand" "=r"))
7073 (clobber (match_scratch:SI 7 "=&r"))
7074 (clobber (match_scratch:SI 8 "=l"))]
6a4cee5f
MM
7075 "DEFAULT_ABI == ABI_AIX
7076 && (INTVAL (operands[3]) == CALL_NORMAL || (INTVAL (operands[3]) & CALL_LONG) != 0)"
b6c9286a 7077 "{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
7078 [(set_attr "type" "load")
7079 (set_attr "length" "28")])
b6c9286a
MM
7080
7081;; A function pointer undef NT is a pointer to a data area whose first word
7082;; contains the actual address of the function, whose second word contains a
7083;; pointer to its TOC. The static chain is not stored under NT, which means
7084;; that we need a trampoline.
7085;;
7086;; operands[0] is an SImode pseudo in which we place the address of the function.
7087;; operands[1] is the stack size to clean up
7088;; operands[2] is the value FUNCTION_ARG returns for the VOID argument (must be 0 for NT)
7089;; operands[3] is location to store the TOC
7090;; operands[4] is the TOC register
7091;;
7092;; We do not break this into separate insns, so that the scheduler will not try
7093;; to move the load of the new TOC before any loads from the TOC.
7094
7095(define_insn "call_indirect_nt"
7096 [(call (mem:SI (match_operand:SI 0 "register_operand" "b"))
7097 (match_operand 1 "const_int_operand" "n"))
6a4cee5f 7098 (use (match_operand 2 "const_int_operand" "n"))
b6c9286a
MM
7099 (use (match_operand 3 "offsettable_addr_operand" "p"))
7100 (use (match_operand 4 "register_operand" "r"))
7101 (clobber (match_scratch:SI 5 "=&r"))
7102 (clobber (match_scratch:SI 6 "=l"))]
6a4cee5f
MM
7103 "DEFAULT_ABI == ABI_NT
7104 && (INTVAL (operands[2]) == CALL_NORMAL || (INTVAL (operands[2]) & CALL_LONG) != 0)"
e1f83b4d 7105 "{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
7106 [(set_attr "type" "load")
7107 (set_attr "length" "24")])
b6c9286a
MM
7108
7109(define_insn "call_value_indirect_nt"
7110 [(set (match_operand 0 "register_operand" "fg")
7111 (call (mem:SI (match_operand:SI 1 "register_operand" "b"))
7112 (match_operand 2 "const_int_operand" "n")))
6a4cee5f 7113 (use (match_operand 3 "const_int_operand" "n"))
b6c9286a
MM
7114 (use (match_operand 4 "offsettable_addr_operand" "p"))
7115 (use (match_operand 5 "register_operand" "r"))
7116 (clobber (match_scratch:SI 6 "=&r"))
7117 (clobber (match_scratch:SI 7 "=l"))]
6a4cee5f
MM
7118 "DEFAULT_ABI == ABI_NT
7119 && (INTVAL (operands[3]) == CALL_NORMAL || (INTVAL (operands[3]) & CALL_LONG) != 0)"
e1f83b4d 7120 "{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
7121 [(set_attr "type" "load")
7122 (set_attr "length" "24")])
b6c9286a
MM
7123
7124;; A function pointer under System V is just a normal pointer
7125;; operands[0] is the function pointer
7126;; operands[1] is the stack size to clean up
7127;; operands[2] is the value FUNCTION_ARG returns for the VOID argument which indicates how to set cr1
7128
7129(define_insn "call_indirect_sysv"
7130 [(call (mem:SI (match_operand:SI 0 "register_operand" "l,l"))
7131 (match_operand 1 "const_int_operand" "n,n"))
7132 (use (match_operand 2 "const_int_operand" "O,n"))
7133 (clobber (match_scratch:SI 3 "=l,l"))]
c81bebd7 7134 "DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS || DEFAULT_ABI == ABI_AIX_NODESC"
b6c9286a
MM
7135 "*
7136{
6a4cee5f
MM
7137 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
7138 output_asm_insn (\"crxor 6,6,6\", operands);
1fd4e8c1 7139
6a4cee5f
MM
7140 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
7141 output_asm_insn (\"creqv 6,6,6\", operands);
b6c9286a
MM
7142
7143 return \"{brl|blrl}\";
7144}"
b7ff3d82
DE
7145 [(set_attr "type" "jmpreg")
7146 (set_attr "length" "4,8")])
b6c9286a
MM
7147
7148(define_insn "call_value_indirect_sysv"
7149 [(set (match_operand 0 "register_operand" "=fg,fg")
7150 (call (mem:SI (match_operand:SI 1 "register_operand" "l,l"))
7151 (match_operand 2 "const_int_operand" "n,n")))
7152 (use (match_operand 3 "const_int_operand" "O,n"))
7153 (clobber (match_scratch:SI 4 "=l,l"))]
c81bebd7 7154 "DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS || DEFAULT_ABI == ABI_AIX_NODESC"
b6c9286a
MM
7155 "*
7156{
6a4cee5f
MM
7157 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
7158 output_asm_insn (\"crxor 6,6,6\", operands);
b6c9286a 7159
6a4cee5f
MM
7160 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
7161 output_asm_insn (\"creqv 6,6,6\", operands);
b6c9286a
MM
7162
7163 return \"{brl|blrl}\";
7164}"
b7ff3d82
DE
7165 [(set_attr "type" "jmpreg")
7166 (set_attr "length" "4,8")])
1fd4e8c1 7167
b6c9286a 7168;; Now the definitions for the call and call_value insns
1fd4e8c1
RK
7169(define_expand "call"
7170 [(parallel [(call (mem:SI (match_operand:SI 0 "address_operand" ""))
7171 (match_operand 1 "" ""))
4697a36c 7172 (use (match_operand 2 "" ""))
1fd4e8c1
RK
7173 (clobber (scratch:SI))])]
7174 ""
7175 "
7176{
7177 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != CONST_INT)
7178 abort ();
7179
7180 operands[0] = XEXP (operands[0], 0);
7509c759
MM
7181
7182 /* Convert NT DLL imports into an indirect call. */
7183 if (GET_CODE (operands[0]) == SYMBOL_REF
6a4cee5f 7184 && (INTVAL (operands[2]) & CALL_NT_DLLIMPORT) != 0)
7509c759
MM
7185 {
7186 operands[0] = rs6000_dll_import_ref (operands[0]);
7187 operands[2] = GEN_INT ((int)CALL_NORMAL);
7188 }
7189
6a4cee5f
MM
7190 if (GET_CODE (operands[0]) != SYMBOL_REF
7191 || (INTVAL (operands[2]) & CALL_LONG) != 0)
1fd4e8c1 7192 {
6a4cee5f
MM
7193 if (INTVAL (operands[2]) & CALL_LONG)
7194 operands[0] = rs6000_longcall_ref (operands[0]);
7195
c81bebd7 7196 if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_SOLARIS)
b6c9286a
MM
7197 emit_call_insn (gen_call_indirect_sysv (force_reg (Pmode, operands[0]),
7198 operands[1], operands[2]));
7199 else
7200 {
7201 rtx toc_reg = gen_rtx (REG, Pmode, 2);
7202 rtx toc_addr = RS6000_SAVE_TOC;
1fd4e8c1 7203
b6c9286a
MM
7204 if (DEFAULT_ABI == ABI_AIX)
7205 {
7206 /* AIX function pointers are really pointers to a three word area */
7207 rtx static_chain = gen_rtx (REG, Pmode, STATIC_CHAIN_REGNUM);
7208 emit_call_insn (gen_call_indirect_aix (force_reg (Pmode, operands[0]),
7209 operands[1], operands[2],
7210 toc_addr, toc_reg, static_chain));
7211 }
7212 else if (DEFAULT_ABI == ABI_NT)
7213 {
7214 /* NT function pointers are really pointers to a two word area */
7215 emit_call_insn (gen_call_indirect_nt (force_reg (Pmode, operands[0]),
7216 operands[1], operands[2],
7217 toc_addr, toc_reg));
7218 }
7219 else
7220 abort ();
7221 }
7222 DONE;
1fd4e8c1
RK
7223 }
7224}")
7225
7226(define_expand "call_value"
7227 [(parallel [(set (match_operand 0 "" "")
7228 (call (mem:SI (match_operand:SI 1 "address_operand" ""))
7229 (match_operand 2 "" "")))
4697a36c 7230 (use (match_operand 3 "" ""))
1fd4e8c1
RK
7231 (clobber (scratch:SI))])]
7232 ""
7233 "
7234{
7235 if (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != CONST_INT)
7236 abort ();
7237
7238 operands[1] = XEXP (operands[1], 0);
7509c759
MM
7239
7240 /* Convert NT DLL imports into an indirect call. */
7241 if (GET_CODE (operands[1]) == SYMBOL_REF
6a4cee5f 7242 && (INTVAL (operands[3]) & CALL_NT_DLLIMPORT) != 0)
7509c759
MM
7243 {
7244 operands[1] = rs6000_dll_import_ref (operands[1]);
7245 operands[3] = GEN_INT ((int)CALL_NORMAL);
7246 }
7247
6a4cee5f
MM
7248 if (GET_CODE (operands[1]) != SYMBOL_REF
7249 || (INTVAL (operands[3]) & CALL_LONG) != 0)
1fd4e8c1 7250 {
6a4cee5f
MM
7251 if (INTVAL (operands[2]) & CALL_LONG)
7252 operands[1] = rs6000_longcall_ref (operands[1]);
7253
c81bebd7 7254 if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_SOLARIS)
b6c9286a
MM
7255 emit_call_insn (gen_call_value_indirect_sysv (operands[0], operands[1],
7256 operands[2], operands[3]));
7257 else
7258 {
7259 rtx toc_reg = gen_rtx (REG, Pmode, 2);
7260 rtx toc_addr = RS6000_SAVE_TOC;
1fd4e8c1 7261
b6c9286a
MM
7262 if (DEFAULT_ABI == ABI_AIX)
7263 {
7264 /* AIX function pointers are really pointers to a three word area */
7265 rtx static_chain = gen_rtx (REG, Pmode, STATIC_CHAIN_REGNUM);
7266 emit_call_insn (gen_call_value_indirect_aix (operands[0],
7267 force_reg (Pmode, operands[1]),
7268 operands[2], operands[3],
7269 toc_addr, toc_reg, static_chain));
7270 }
7271 else if (DEFAULT_ABI == ABI_NT)
7272 {
7273 /* NT function pointers are really pointers to a two word area */
7274 emit_call_insn (gen_call_value_indirect_nt (operands[0],
7275 force_reg (Pmode, operands[1]),
7276 operands[2], operands[3],
7277 toc_addr, toc_reg));
7278 }
7279 else
7280 abort ();
7281 }
7282 DONE;
1fd4e8c1
RK
7283 }
7284}")
7285
04780ee7 7286;; Call to function in current module. No TOC pointer reload needed.
4697a36c
MM
7287;; Operand2 is non-zero if we are using the V.4 calling sequence and
7288;; either the function was not prototyped, or it was prototyped as a
7289;; variable argument function. It is > 0 if FP registers were passed
7290;; and < 0 if they were not.
04780ee7
RK
7291
7292(define_insn ""
4697a36c
MM
7293 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
7294 (match_operand 1 "" "g,g"))
7295 (use (match_operand:SI 2 "immediate_operand" "O,n"))
7296 (clobber (match_scratch:SI 3 "=l,l"))]
5a19791c 7297 "(INTVAL (operands[2]) & CALL_LONG) == 0"
4697a36c
MM
7298 "*
7299{
6a4cee5f
MM
7300 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
7301 output_asm_insn (\"crxor 6,6,6\", operands);
7302
7303 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
7304 output_asm_insn (\"creqv 6,6,6\", operands);
4697a36c
MM
7305
7306 return \"bl %z0\";
7307}"
b7ff3d82
DE
7308 [(set_attr "type" "branch")
7309 (set_attr "length" "4,8")])
04780ee7
RK
7310
7311;; Call to function which may be in another module. Restore the TOC
911f679c 7312;; pointer (r2) after the call unless this is System V.
4697a36c
MM
7313;; Operand2 is non-zero if we are using the V.4 calling sequence and
7314;; either the function was not prototyped, or it was prototyped as a
7315;; variable argument function. It is > 0 if FP registers were passed
7316;; and < 0 if they were not.
04780ee7 7317
1fd4e8c1 7318(define_insn ""
b6c9286a
MM
7319 [(call (mem:SI (match_operand:SI 0 "call_operand" "s,s"))
7320 (match_operand 1 "" "fg,fg"))
7321 (use (match_operand:SI 2 "immediate_operand" "O,n"))
7322 (clobber (match_scratch:SI 3 "=l,l"))]
6a4cee5f 7323 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
5a19791c 7324 && (INTVAL (operands[2]) & CALL_LONG) == 0"
911f679c
MM
7325 "*
7326{
b6c9286a 7327 /* Indirect calls should go through call_indirect */
0f07e76c 7328 if (GET_CODE (operands[0]) == REG)
b6c9286a 7329 abort ();
911f679c 7330
6a4cee5f
MM
7331 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
7332 output_asm_insn (\"crxor 6,6,6\", operands);
7333
7334 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
7335 output_asm_insn (\"creqv 6,6,6\", operands);
7509c759 7336
b6c9286a
MM
7337 return (TARGET_WINDOWS_NT) ? \"bl %z0\;.znop %z0\" : \"bl %z0\;%.\";
7338}"
b7ff3d82
DE
7339 [(set_attr "type" "branch")
7340 (set_attr "length" "8,12")])
59313e4e 7341
b6c9286a
MM
7342(define_insn ""
7343 [(call (mem:SI (match_operand:SI 0 "call_operand" "s,s"))
7344 (match_operand 1 "" "fg,fg"))
7345 (use (match_operand:SI 2 "immediate_operand" "O,n"))
7346 (clobber (match_scratch:SI 3 "=l,l"))]
c81bebd7 7347 "(DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
5a19791c 7348 && (INTVAL (operands[2]) & CALL_LONG) == 0"
b6c9286a
MM
7349 "*
7350{
b6c9286a 7351 /* Indirect calls should go through call_indirect */
0f07e76c 7352 if (GET_CODE (operands[0]) == REG)
b6c9286a 7353 abort ();
59313e4e 7354
6a4cee5f
MM
7355 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
7356 output_asm_insn (\"crxor 6,6,6\", operands);
7357
7358 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
7359 output_asm_insn (\"creqv 6,6,6\", operands);
7509c759 7360
d266da75 7361 return \"bl %z0\";
911f679c 7362}"
b7ff3d82
DE
7363 [(set_attr "type" "branch")
7364 (set_attr "length" "4,8")])
1fd4e8c1 7365
04780ee7 7366(define_insn ""
4697a36c
MM
7367 [(set (match_operand 0 "" "=fg,fg")
7368 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
7369 (match_operand 2 "" "g,g")))
7370 (use (match_operand:SI 3 "immediate_operand" "O,n"))
7371 (clobber (match_scratch:SI 4 "=l,l"))]
5a19791c 7372 "(INTVAL (operands[3]) & CALL_LONG) == 0"
4697a36c
MM
7373 "*
7374{
6a4cee5f
MM
7375 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
7376 output_asm_insn (\"crxor 6,6,6\", operands);
7377
7378 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
7379 output_asm_insn (\"creqv 6,6,6\", operands);
4697a36c
MM
7380
7381 return \"bl %z1\";
7382}"
b7ff3d82
DE
7383 [(set_attr "type" "branch")
7384 (set_attr "length" "4,8")])
04780ee7 7385
1fd4e8c1 7386(define_insn ""
b6c9286a
MM
7387 [(set (match_operand 0 "" "=fg,fg")
7388 (call (mem:SI (match_operand:SI 1 "call_operand" "s,s"))
7389 (match_operand 2 "" "fg,fg")))
7390 (use (match_operand:SI 3 "immediate_operand" "O,n"))
7391 (clobber (match_scratch:SI 4 "=l,l"))]
6a4cee5f 7392 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
5a19791c 7393 && (INTVAL (operands[3]) & CALL_LONG) == 0"
911f679c
MM
7394 "*
7395{
b6c9286a 7396 /* This should be handled by call_value_indirect */
59313e4e 7397 if (GET_CODE (operands[1]) == REG)
b6c9286a
MM
7398 abort ();
7399
6a4cee5f
MM
7400 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
7401 output_asm_insn (\"crxor 6,6,6\", operands);
7402
7403 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
7404 output_asm_insn (\"creqv 6,6,6\", operands);
7509c759 7405
b6c9286a
MM
7406 return (TARGET_WINDOWS_NT) ? \"bl %z1\;.znop %z1\" : \"bl %z1\;%.\";
7407}"
b7ff3d82
DE
7408 [(set_attr "type" "branch")
7409 (set_attr "length" "8,12")])
b6c9286a
MM
7410
7411(define_insn ""
7412 [(set (match_operand 0 "" "=fg,fg")
7413 (call (mem:SI (match_operand:SI 1 "call_operand" "s,s"))
7414 (match_operand 2 "" "fg,fg")))
7415 (use (match_operand:SI 3 "immediate_operand" "O,n"))
7416 (clobber (match_scratch:SI 4 "=l,l"))]
c81bebd7 7417 "(DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
5a19791c 7418 && (INTVAL (operands[3]) & CALL_LONG) == 0"
b6c9286a
MM
7419 "*
7420{
b6c9286a 7421 /* This should be handled by call_value_indirect */
59313e4e 7422 if (GET_CODE (operands[1]) == REG)
b6c9286a 7423 abort ();
59313e4e 7424
6a4cee5f
MM
7425 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
7426 output_asm_insn (\"crxor 6,6,6\", operands);
7427
7428 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
7429 output_asm_insn (\"creqv 6,6,6\", operands);
7509c759 7430
d266da75 7431 return \"bl %z1\";
911f679c 7432}"
b7ff3d82
DE
7433 [(set_attr "type" "branch")
7434 (set_attr "length" "4,8")])
e6f948e3
RK
7435
7436;; Call subroutine returning any type.
e6f948e3
RK
7437(define_expand "untyped_call"
7438 [(parallel [(call (match_operand 0 "" "")
7439 (const_int 0))
7440 (match_operand 1 "" "")
7441 (match_operand 2 "" "")])]
7442 ""
7443 "
7444{
7445 int i;
7446
4697a36c 7447 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx, const0_rtx));
e6f948e3
RK
7448
7449 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7450 {
7451 rtx set = XVECEXP (operands[2], 0, i);
7452 emit_move_insn (SET_DEST (set), SET_SRC (set));
7453 }
7454
7455 /* The optimizer does not know that the call sets the function value
7456 registers we stored in the result block. We avoid problems by
7457 claiming that all hard registers are used and clobbered at this
7458 point. */
7459 emit_insn (gen_blockage ());
7460
7461 DONE;
7462}")
7463
7464;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7465;; all of memory. This blocks insns from being moved across this point.
7466
7467(define_insn "blockage"
7468 [(unspec_volatile [(const_int 0)] 0)]
7469 ""
7470 "")
4697a36c 7471
b6c9286a
MM
7472;; Synchronize instructions/data caches for V.4 trampolines
7473;; The extra memory_operand is to prevent the optimizer from
7474;; deleting insns with "no" effect.
7475(define_insn "icbi"
7476 [(unspec [(match_operand 0 "memory_operand" "=m")
7477 (match_operand 1 "register_operand" "b")
7478 (match_operand 2 "register_operand" "r")] 3)]
7479 "TARGET_POWERPC"
7480 "icbi %1,%2")
7481
7482(define_insn "dcbst"
7483 [(unspec [(match_operand 0 "memory_operand" "=m")
7484 (match_operand 1 "register_operand" "b")
7485 (match_operand 2 "register_operand" "r")] 4)]
7486 "TARGET_POWERPC"
7487 "dcbst %1,%2")
7488
7489(define_insn "sync"
7490 [(unspec [(match_operand 0 "memory_operand" "=m")] 5)]
4697a36c 7491 ""
b6c9286a
MM
7492 "{dcs|sync}")
7493
7494(define_insn "isync"
7495 [(unspec [(match_operand 0 "memory_operand" "=m")] 6)]
7496 ""
7497 "{ics|isync}")
4697a36c 7498
766a866c
MM
7499
7500;; V.4 specific code to initialize the PIC register
7501
7502(define_insn "init_v4_pic"
7503 [(set (match_operand:SI 0 "register_operand" "=l")
7504 (unspec [(const_int 0)] 7))]
c81bebd7 7505 "DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS"
766a866c
MM
7506 "bl _GLOBAL_OFFSET_TABLE_-4"
7507 [(set_attr "type" "branch")])
7508
1fd4e8c1
RK
7509\f
7510;; Compare insns are next. Note that the RS/6000 has two types of compares,
7e69e155 7511;; signed & unsigned, and one type of branch.
1fd4e8c1
RK
7512;;
7513;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
7514;; insns, and branches. We store the operands of compares until we see
7515;; how it is used.
7516(define_expand "cmpsi"
7517 [(set (cc0)
cd2b37d9 7518 (compare (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7519 (match_operand:SI 1 "reg_or_short_operand" "")))]
7520 ""
7521 "
7522{
7523 /* Take care of the possibility that operands[1] might be negative but
7524 this might be a logical operation. That insn doesn't exist. */
7525 if (GET_CODE (operands[1]) == CONST_INT
7526 && INTVAL (operands[1]) < 0)
7527 operands[1] = force_reg (SImode, operands[1]);
7528
7529 rs6000_compare_op0 = operands[0];
7530 rs6000_compare_op1 = operands[1];
7531 rs6000_compare_fp_p = 0;
7532 DONE;
7533}")
7534
266eb58a
DE
7535(define_expand "cmpdi"
7536 [(set (cc0)
7537 (compare (match_operand:DI 0 "gpc_reg_operand" "")
7538 (match_operand:DI 1 "reg_or_short_operand" "")))]
7539 "TARGET_POWERPC64"
7540 "
7541{
7542 /* Take care of the possibility that operands[1] might be negative but
7543 this might be a logical operation. That insn doesn't exist. */
7544 if (GET_CODE (operands[1]) == CONST_INT
7545 && INTVAL (operands[1]) < 0)
7546 operands[1] = force_reg (DImode, operands[1]);
7547
7548 rs6000_compare_op0 = operands[0];
7549 rs6000_compare_op1 = operands[1];
7550 rs6000_compare_fp_p = 0;
7551 DONE;
7552}")
7553
1fd4e8c1 7554(define_expand "cmpsf"
cd2b37d9
RK
7555 [(set (cc0) (compare (match_operand:SF 0 "gpc_reg_operand" "")
7556 (match_operand:SF 1 "gpc_reg_operand" "")))]
d14a6d05 7557 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
7558 "
7559{
7560 rs6000_compare_op0 = operands[0];
7561 rs6000_compare_op1 = operands[1];
7562 rs6000_compare_fp_p = 1;
7563 DONE;
7564}")
7565
7566(define_expand "cmpdf"
cd2b37d9
RK
7567 [(set (cc0) (compare (match_operand:DF 0 "gpc_reg_operand" "")
7568 (match_operand:DF 1 "gpc_reg_operand" "")))]
d14a6d05 7569 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
7570 "
7571{
7572 rs6000_compare_op0 = operands[0];
7573 rs6000_compare_op1 = operands[1];
7574 rs6000_compare_fp_p = 1;
7575 DONE;
7576}")
7577
7578(define_expand "beq"
7579 [(set (match_dup 2) (match_dup 1))
7580 (set (pc)
7581 (if_then_else (eq (match_dup 2)
7582 (const_int 0))
7583 (label_ref (match_operand 0 "" ""))
7584 (pc)))]
7585 ""
7586 "
7587{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7588 operands[1] = gen_rtx (COMPARE, mode,
7589 rs6000_compare_op0, rs6000_compare_op1);
7590 operands[2] = gen_reg_rtx (mode);
7591}")
7592
7593(define_expand "bne"
7594 [(set (match_dup 2) (match_dup 1))
7595 (set (pc)
7596 (if_then_else (ne (match_dup 2)
7597 (const_int 0))
7598 (label_ref (match_operand 0 "" ""))
7599 (pc)))]
7600 ""
7601 "
7602{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7603 operands[1] = gen_rtx (COMPARE, mode,
7604 rs6000_compare_op0, rs6000_compare_op1);
7605 operands[2] = gen_reg_rtx (mode);
7606}")
7607
7608(define_expand "blt"
7609 [(set (match_dup 2) (match_dup 1))
7610 (set (pc)
7611 (if_then_else (lt (match_dup 2)
7612 (const_int 0))
7613 (label_ref (match_operand 0 "" ""))
7614 (pc)))]
7615 ""
7616 "
7617{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7618 operands[1] = gen_rtx (COMPARE, mode,
7619 rs6000_compare_op0, rs6000_compare_op1);
7620 operands[2] = gen_reg_rtx (mode);
7621}")
7622
7623(define_expand "bgt"
7624 [(set (match_dup 2) (match_dup 1))
7625 (set (pc)
7626 (if_then_else (gt (match_dup 2)
7627 (const_int 0))
7628 (label_ref (match_operand 0 "" ""))
7629 (pc)))]
7630 ""
7631 "
7632{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7633 operands[1] = gen_rtx (COMPARE, mode,
7634 rs6000_compare_op0, rs6000_compare_op1);
7635 operands[2] = gen_reg_rtx (mode);
7636}")
7637
7638(define_expand "ble"
7639 [(set (match_dup 2) (match_dup 1))
7640 (set (pc)
7641 (if_then_else (le (match_dup 2)
7642 (const_int 0))
7643 (label_ref (match_operand 0 "" ""))
7644 (pc)))]
7645 ""
7646 "
7647{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7648 operands[1] = gen_rtx (COMPARE, mode,
7649 rs6000_compare_op0, rs6000_compare_op1);
7650 operands[2] = gen_reg_rtx (mode);
7651}")
7652
7653(define_expand "bge"
7654 [(set (match_dup 2) (match_dup 1))
7655 (set (pc)
7656 (if_then_else (ge (match_dup 2)
7657 (const_int 0))
7658 (label_ref (match_operand 0 "" ""))
7659 (pc)))]
7660 ""
7661 "
7662{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7663 operands[1] = gen_rtx (COMPARE, mode,
7664 rs6000_compare_op0, rs6000_compare_op1);
7665 operands[2] = gen_reg_rtx (mode);
7666}")
7667
7668(define_expand "bgtu"
7669 [(set (match_dup 2) (match_dup 1))
7670 (set (pc)
7671 (if_then_else (gtu (match_dup 2)
7672 (const_int 0))
7673 (label_ref (match_operand 0 "" ""))
7674 (pc)))]
7675 ""
7676 "
7677{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
7678 rs6000_compare_op0, rs6000_compare_op1);
7679 operands[2] = gen_reg_rtx (CCUNSmode);
7680}")
7681
7682(define_expand "bltu"
7683 [(set (match_dup 2) (match_dup 1))
7684 (set (pc)
7685 (if_then_else (ltu (match_dup 2)
7686 (const_int 0))
7687 (label_ref (match_operand 0 "" ""))
7688 (pc)))]
7689 ""
7690 "
7691{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
7692 rs6000_compare_op0, rs6000_compare_op1);
7693 operands[2] = gen_reg_rtx (CCUNSmode);
7694}")
7695
7696(define_expand "bgeu"
7697 [(set (match_dup 2) (match_dup 1))
7698 (set (pc)
7699 (if_then_else (geu (match_dup 2)
7700 (const_int 0))
7701 (label_ref (match_operand 0 "" ""))
7702 (pc)))]
7703 ""
7704 "
7705{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
7706 rs6000_compare_op0, rs6000_compare_op1);
7707 operands[2] = gen_reg_rtx (CCUNSmode);
7708}")
7709
7710(define_expand "bleu"
7711 [(set (match_dup 2) (match_dup 1))
7712 (set (pc)
7713 (if_then_else (leu (match_dup 2)
7714 (const_int 0))
7715 (label_ref (match_operand 0 "" ""))
7716 (pc)))]
7717 ""
7718 "
7719{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
7720 rs6000_compare_op0, rs6000_compare_op1);
7721 operands[2] = gen_reg_rtx (CCUNSmode);
7722}")
7723
7724;; For SNE, we would prefer that the xor/abs sequence be used for integers.
7725;; For SEQ, likewise, except that comparisons with zero should be done
7726;; with an scc insns. However, due to the order that combine see the
7727;; resulting insns, we must, in fact, allow SEQ for integers. Fail in
7728;; the cases we don't want to handle.
7729(define_expand "seq"
7730 [(set (match_dup 2) (match_dup 1))
cd2b37d9 7731 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7732 (eq:SI (match_dup 2) (const_int 0)))]
7733 ""
7734 "
7735{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7736 operands[1] = gen_rtx (COMPARE, mode,
7737 rs6000_compare_op0, rs6000_compare_op1);
7738 operands[2] = gen_reg_rtx (mode);
7739}")
7740
7741(define_expand "sne"
7742 [(set (match_dup 2) (match_dup 1))
cd2b37d9 7743 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7744 (ne:SI (match_dup 2) (const_int 0)))]
7745 ""
7746 "
7747{ if (! rs6000_compare_fp_p)
7748 FAIL;
7749
7750 operands[1] = gen_rtx (COMPARE, CCFPmode,
7751 rs6000_compare_op0, rs6000_compare_op1);
7752 operands[2] = gen_reg_rtx (CCFPmode);
7753}")
7754
7755;; A > 0 is best done using the portable sequence, so fail in that case.
7756(define_expand "sgt"
7757 [(set (match_dup 2) (match_dup 1))
cd2b37d9 7758 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7759 (gt:SI (match_dup 2) (const_int 0)))]
7760 ""
7761 "
7762{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7763
7764 if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
7765 FAIL;
7766
7767 operands[1] = gen_rtx (COMPARE, mode,
7768 rs6000_compare_op0, rs6000_compare_op1);
7769 operands[2] = gen_reg_rtx (mode);
7770}")
7771
7772;; A < 0 is best done in the portable way for A an integer.
7773(define_expand "slt"
7774 [(set (match_dup 2) (match_dup 1))
cd2b37d9 7775 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7776 (lt:SI (match_dup 2) (const_int 0)))]
7777 ""
7778 "
7779{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7780
7781 if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
7782 FAIL;
7783
7784 operands[1] = gen_rtx (COMPARE, mode,
7785 rs6000_compare_op0, rs6000_compare_op1);
7786 operands[2] = gen_reg_rtx (mode);
7787}")
7788
7789(define_expand "sge"
7790 [(set (match_dup 2) (match_dup 1))
cd2b37d9 7791 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7792 (ge:SI (match_dup 2) (const_int 0)))]
7793 ""
7794 "
7795{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7796 operands[1] = gen_rtx (COMPARE, mode,
7797 rs6000_compare_op0, rs6000_compare_op1);
7798 operands[2] = gen_reg_rtx (mode);
7799}")
7800
7801;; A <= 0 is best done the portable way for A an integer.
7802(define_expand "sle"
7803 [(set (match_dup 2) (match_dup 1))
cd2b37d9 7804 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7805 (le:SI (match_dup 2) (const_int 0)))]
7806 ""
7807 "
7808{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
7809
7810 if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
7811 FAIL;
7812
7813 operands[1] = gen_rtx (COMPARE, mode,
7814 rs6000_compare_op0, rs6000_compare_op1);
7815 operands[2] = gen_reg_rtx (mode);
7816}")
7817
7818(define_expand "sgtu"
7819 [(set (match_dup 2) (match_dup 1))
cd2b37d9 7820 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7821 (gtu:SI (match_dup 2) (const_int 0)))]
7822 ""
7823 "
7824{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
7825 rs6000_compare_op0, rs6000_compare_op1);
7826 operands[2] = gen_reg_rtx (CCUNSmode);
7827}")
7828
7829(define_expand "sltu"
7830 [(set (match_dup 2) (match_dup 1))
cd2b37d9 7831 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7832 (ltu:SI (match_dup 2) (const_int 0)))]
7833 ""
7834 "
7835{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
7836 rs6000_compare_op0, rs6000_compare_op1);
7837 operands[2] = gen_reg_rtx (CCUNSmode);
7838}")
7839
7840(define_expand "sgeu"
7841 [(set (match_dup 2) (match_dup 1))
cd2b37d9 7842 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7843 (geu:SI (match_dup 2) (const_int 0)))]
7844 ""
7845 "
7846{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
7847 rs6000_compare_op0, rs6000_compare_op1);
7848 operands[2] = gen_reg_rtx (CCUNSmode);
7849}")
7850
7851(define_expand "sleu"
7852 [(set (match_dup 2) (match_dup 1))
cd2b37d9 7853 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7854 (leu:SI (match_dup 2) (const_int 0)))]
7855 ""
7856 "
7857{ operands[1] = gen_rtx (COMPARE, CCUNSmode,
7858 rs6000_compare_op0, rs6000_compare_op1);
7859 operands[2] = gen_reg_rtx (CCUNSmode);
7860}")
7861\f
7862;; Here are the actual compare insns.
7863(define_insn ""
7864 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
cd2b37d9 7865 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
7866 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
7867 ""
7f340546 7868 "{cmp%I2|cmpw%I2} %0,%1,%2"
1fd4e8c1
RK
7869 [(set_attr "type" "compare")])
7870
266eb58a
DE
7871(define_insn ""
7872 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
7873 (compare:CC (match_operand:DI 1 "gpc_reg_operand" "r")
7874 (match_operand:DI 2 "reg_or_short_operand" "rI")))]
7875 "TARGET_POWERPC64"
7876 "cmpd%I2 %0,%1,%2"
7877 [(set_attr "type" "compare")])
7878
f357808b
RK
7879;; If we are comparing a register for equality with a large constant,
7880;; we can do this with an XOR followed by a compare. But we need a scratch
7881;; register for the result of the XOR.
7882
7883(define_split
7884 [(set (match_operand:CC 0 "cc_reg_operand" "")
cd2b37d9 7885 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
f357808b 7886 (match_operand:SI 2 "non_short_cint_operand" "")))
cd2b37d9 7887 (clobber (match_operand:SI 3 "gpc_reg_operand" ""))]
f357808b
RK
7888 "find_single_use (operands[0], insn, 0)
7889 && (GET_CODE (*find_single_use (operands[0], insn, 0)) == EQ
7890 || GET_CODE (*find_single_use (operands[0], insn, 0)) == NE)"
7891 [(set (match_dup 3) (xor:SI (match_dup 1) (match_dup 4)))
7892 (set (match_dup 0) (compare:CC (match_dup 3) (match_dup 5)))]
7893 "
7894{
7895 /* Get the constant we are comparing against, C, and see what it looks like
7896 sign-extended to 16 bits. Then see what constant could be XOR'ed
7897 with C to get the sign-extended value. */
7898
7899 int c = INTVAL (operands[2]);
7900 int sextc = (c << 16) >> 16;
7901 int xorv = c ^ sextc;
7902
7903 operands[4] = gen_rtx (CONST_INT, VOIDmode, xorv);
7904 operands[5] = gen_rtx (CONST_INT, VOIDmode, sextc);
7905}")
7906
1fd4e8c1
RK
7907(define_insn ""
7908 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
cd2b37d9 7909 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
7910 (match_operand:SI 2 "reg_or_u_short_operand" "rI")))]
7911 ""
7f340546 7912 "{cmpl%I2|cmplw%I2} %0,%1,%W2"
1fd4e8c1
RK
7913 [(set_attr "type" "compare")])
7914
266eb58a
DE
7915(define_insn ""
7916 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
7917 (compare:CCUNS (match_operand:DI 1 "gpc_reg_operand" "r")
7918 (match_operand:DI 2 "reg_or_u_short_operand" "rI")))]
7919 ""
7920 "cmpld%I2 %0,%1,%W2"
7921 [(set_attr "type" "compare")])
7922
1fd4e8c1
RK
7923;; The following two insns don't exist as single insns, but if we provide
7924;; them, we can swap an add and compare, which will enable us to overlap more
7925;; of the required delay between a compare and branch. We generate code for
7926;; them by splitting.
7927
7928(define_insn ""
7929 [(set (match_operand:CC 3 "cc_reg_operand" "=y")
cd2b37d9 7930 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 7931 (match_operand:SI 2 "short_cint_operand" "i")))
cd2b37d9 7932 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
7933 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
7934 ""
baf97f86
RK
7935 "#"
7936 [(set_attr "length" "8")])
7e69e155 7937
1fd4e8c1
RK
7938(define_insn ""
7939 [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
cd2b37d9 7940 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 7941 (match_operand:SI 2 "u_short_cint_operand" "i")))
cd2b37d9 7942 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
7943 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
7944 ""
baf97f86
RK
7945 "#"
7946 [(set_attr "length" "8")])
7e69e155 7947
1fd4e8c1
RK
7948(define_split
7949 [(set (match_operand:CC 3 "cc_reg_operand" "")
cd2b37d9 7950 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1 7951 (match_operand:SI 2 "short_cint_operand" "")))
cd2b37d9 7952 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7953 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
7954 ""
7955 [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
7956 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
7957
7958(define_split
7959 [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
cd2b37d9 7960 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1 7961 (match_operand:SI 2 "u_short_cint_operand" "")))
cd2b37d9 7962 (set (match_operand:SI 0 "gpc_reg_operand" "")
1fd4e8c1
RK
7963 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
7964 ""
7965 [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
7966 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
7967
7968(define_insn ""
7969 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
cd2b37d9
RK
7970 (compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "f")
7971 (match_operand:SF 2 "gpc_reg_operand" "f")))]
d14a6d05 7972 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
7973 "fcmpu %0,%1,%2"
7974 [(set_attr "type" "fpcompare")])
7975
7976(define_insn ""
7977 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
cd2b37d9
RK
7978 (compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "f")
7979 (match_operand:DF 2 "gpc_reg_operand" "f")))]
d14a6d05 7980 "TARGET_HARD_FLOAT"
1fd4e8c1
RK
7981 "fcmpu %0,%1,%2"
7982 [(set_attr "type" "fpcompare")])
7983\f
7984;; Now we have the scc insns. We can do some combinations because of the
7985;; way the machine works.
7986;;
7987;; Note that this is probably faster if we can put an insn between the
c5defebb
RK
7988;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
7989;; cases the insns below which don't use an intermediate CR field will
7990;; be used instead.
1fd4e8c1 7991(define_insn ""
cd2b37d9 7992 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
7993 (match_operator:SI 1 "scc_comparison_operator"
7994 [(match_operand 2 "cc_reg_operand" "y")
7995 (const_int 0)]))]
7996 ""
ca7f5001 7997 "%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%J1,1"
b19003d8 7998 [(set_attr "length" "12")])
1fd4e8c1
RK
7999
8000(define_insn ""
8001 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
8002 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
8003 [(match_operand 2 "cc_reg_operand" "y")
8004 (const_int 0)])
8005 (const_int 0)))
cd2b37d9 8006 (set (match_operand:SI 3 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8007 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8008 ""
ca7f5001 8009 "%D1mfcr %3\;{rlinm.|rlwinm.} %3,%3,%J1,1"
b19003d8
RK
8010 [(set_attr "type" "delayed_compare")
8011 (set_attr "length" "12")])
1fd4e8c1
RK
8012
8013(define_insn ""
cd2b37d9 8014 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8015 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
8016 [(match_operand 2 "cc_reg_operand" "y")
8017 (const_int 0)])
8018 (match_operand:SI 3 "const_int_operand" "n")))]
8019 ""
8020 "*
8021{
8022 int is_bit = ccr_bit (operands[1], 1);
8023 int put_bit = 31 - (INTVAL (operands[3]) & 31);
8024 int count;
8025
8026 if (is_bit >= put_bit)
8027 count = is_bit - put_bit;
8028 else
8029 count = 32 - (put_bit - is_bit);
8030
8031 operands[4] = gen_rtx (CONST_INT, VOIDmode, count);
8032 operands[5] = gen_rtx (CONST_INT, VOIDmode, put_bit);
8033
ca7f5001 8034 return \"%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%4,%5,%5\";
b19003d8
RK
8035}"
8036 [(set_attr "length" "12")])
1fd4e8c1
RK
8037
8038(define_insn ""
8039 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
8040 (compare:CC
8041 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
8042 [(match_operand 2 "cc_reg_operand" "y")
8043 (const_int 0)])
8044 (match_operand:SI 3 "const_int_operand" "n"))
8045 (const_int 0)))
cd2b37d9 8046 (set (match_operand:SI 4 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8047 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
8048 (match_dup 3)))]
8049 ""
8050 "*
8051{
8052 int is_bit = ccr_bit (operands[1], 1);
8053 int put_bit = 31 - (INTVAL (operands[3]) & 31);
8054 int count;
8055
8056 if (is_bit >= put_bit)
8057 count = is_bit - put_bit;
8058 else
8059 count = 32 - (put_bit - is_bit);
8060
8061 operands[5] = gen_rtx (CONST_INT, VOIDmode, count);
8062 operands[6] = gen_rtx (CONST_INT, VOIDmode, put_bit);
8063
ca7f5001 8064 return \"%D1mfcr %4\;{rlinm.|rlwinm.} %4,%4,%5,%6,%6\";
1fd4e8c1 8065}"
b19003d8
RK
8066 [(set_attr "type" "delayed_compare")
8067 (set_attr "length" "12")])
1fd4e8c1 8068
c5defebb
RK
8069;; If we are comparing the result of two comparisons, this can be done
8070;; using creqv or crxor.
8071
8072(define_insn ""
8073 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
8074 (compare:CCEQ (match_operator 1 "scc_comparison_operator"
8075 [(match_operand 2 "cc_reg_operand" "y")
8076 (const_int 0)])
8077 (match_operator 3 "scc_comparison_operator"
8078 [(match_operand 4 "cc_reg_operand" "y")
8079 (const_int 0)])))]
8080 "REGNO (operands[2]) != REGNO (operands[4])"
8081 "*
8082{
8083 enum rtx_code code1, code2;
8084
8085 code1 = GET_CODE (operands[1]);
8086 code2 = GET_CODE (operands[3]);
8087
8088 if ((code1 == EQ || code1 == LT || code1 == GT
8089 || code1 == LTU || code1 == GTU
8090 || (code1 != NE && GET_MODE (operands[2]) == CCFPmode))
8091 !=
8092 (code2 == EQ || code2 == LT || code2 == GT
8093 || code2 == LTU || code2 == GTU
8094 || (code2 != NE && GET_MODE (operands[4]) == CCFPmode)))
8095 return \"%C1%C3crxor %E0,%j1,%j3\";
8096 else
8097 return \"%C1%C3creqv %E0,%j1,%j3\";
b19003d8
RK
8098}"
8099 [(set_attr "length" "12")])
c5defebb
RK
8100
8101;; There is a 3 cycle delay between consecutive mfcr instructions
8102;; so it is useful to combine 2 scc instructions to use only one mfcr.
8103
8104(define_peephole
cd2b37d9 8105 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
c5defebb
RK
8106 (match_operator:SI 1 "scc_comparison_operator"
8107 [(match_operand 2 "cc_reg_operand" "y")
8108 (const_int 0)]))
cd2b37d9 8109 (set (match_operand:SI 3 "gpc_reg_operand" "=r")
c5defebb
RK
8110 (match_operator:SI 4 "scc_comparison_operator"
8111 [(match_operand 5 "cc_reg_operand" "y")
8112 (const_int 0)]))]
8113 "REGNO (operands[2]) != REGNO (operands[5])"
ca7f5001 8114 "%D1%D4mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1"
b19003d8 8115 [(set_attr "length" "20")])
c5defebb 8116
1fd4e8c1
RK
8117;; There are some scc insns that can be done directly, without a compare.
8118;; These are faster because they don't involve the communications between
8119;; the FXU and branch units. In fact, we will be replacing all of the
8120;; integer scc insns here or in the portable methods in emit_store_flag.
8121;;
8122;; Also support (neg (scc ..)) since that construct is used to replace
8123;; branches, (plus (scc ..) ..) since that construct is common and
8124;; takes no more insns than scc, and (and (neg (scc ..)) ..) in the
8125;; cases where it is no more expensive than (neg (scc ..)).
8126
8127;; Have reload force a constant into a register for the simple insns that
8128;; otherwise won't accept constants. We do this because it is faster than
8129;; the cmp/mfcr sequence we would otherwise generate.
8130
8131(define_insn ""
cd2b37d9
RK
8132 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
8133 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1
RK
8134 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I")))
8135 (clobber (match_scratch:SI 3 "=r,&r,r,r,r"))]
8136 ""
8137 "@
ca7f5001 8138 xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
71d2371f 8139 {sfi|subfic} %3,%1,0\;{ae|adde} %0,%3,%1
ca7f5001
RK
8140 {xoril|xori} %0,%1,%b2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
8141 {xoriu|xoris} %0,%1,%u2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
8142 {sfi|subfic} %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0"
b19003d8 8143 [(set_attr "length" "12,8,12,12,12")])
1fd4e8c1
RK
8144
8145(define_insn ""
8146 [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,x,x,x")
7e69e155 8147 (compare:CC
cd2b37d9 8148 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1
RK
8149 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
8150 (const_int 0)))
cd2b37d9 8151 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
1fd4e8c1
RK
8152 (eq:SI (match_dup 1) (match_dup 2)))
8153 (clobber (match_scratch:SI 3 "=r,&r,r,r,r"))]
8154 ""
8155 "@
ca7f5001
RK
8156 xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
8157 {sfi|subfic} %3,%1,0\;{ae.|adde.} %0,%3,%1
8158 {xoril|xori} %0,%1,%b2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
8159 {xoriu|xoris} %0,%1,%u2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
8160 {sfi|subfic} %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0"
b19003d8
RK
8161 [(set_attr "type" "compare")
8162 (set_attr "length" "12,8,12,12,12")])
8163
8164;; We have insns of the form shown by the first define_insn below. If
8165;; there is something inside the comparison operation, we must split it.
8166(define_split
8167 [(set (match_operand:SI 0 "gpc_reg_operand" "")
8168 (plus:SI (match_operator 1 "comparison_operator"
8169 [(match_operand:SI 2 "" "")
8170 (match_operand:SI 3
8171 "reg_or_cint_operand" "")])
8172 (match_operand:SI 4 "gpc_reg_operand" "")))
8173 (clobber (match_operand:SI 5 "register_operand" ""))]
8174 "! gpc_reg_operand (operands[2], SImode)"
8175 [(set (match_dup 5) (match_dup 2))
8176 (set (match_dup 2) (plus:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
8177 (match_dup 4)))])
1fd4e8c1
RK
8178
8179(define_insn ""
cd2b37d9
RK
8180 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
8181 (plus:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1 8182 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
cd2b37d9 8183 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r")))
1fd4e8c1
RK
8184 (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))]
8185 ""
8186 "@
ca7f5001
RK
8187 xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
8188 {sfi|subfic} %4,%1,0\;{aze|addze} %0,%3
8189 {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
8190 {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
d9d934ef 8191 {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3"
b19003d8 8192 [(set_attr "length" "12,8,12,12,12")])
1fd4e8c1
RK
8193
8194(define_insn ""
8195 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,x")
7e69e155 8196 (compare:CC
1fd4e8c1 8197 (plus:SI
cd2b37d9 8198 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1 8199 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
cd2b37d9 8200 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r"))
1fd4e8c1
RK
8201 (const_int 0)))
8202 (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))]
8203 ""
8204 "@
ca7f5001
RK
8205 xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
8206 {sfi|subfic} %4,%1,0\;{aze.|addze.} %0,%3
8207 {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
8208 {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
8209 {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3"
b19003d8
RK
8210 [(set_attr "type" "compare")
8211 (set_attr "length" "12,8,12,12,12")])
1fd4e8c1
RK
8212
8213(define_insn ""
8214 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x,x,x,x")
7e69e155 8215 (compare:CC
1fd4e8c1 8216 (plus:SI
cd2b37d9 8217 (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1 8218 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))
cd2b37d9 8219 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r"))
1fd4e8c1 8220 (const_int 0)))
cd2b37d9 8221 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
1fd4e8c1
RK
8222 (plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
8223 (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))]
8224 ""
8225 "@
ca7f5001
RK
8226 xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
8227 {sfi|subfic} %4,%1,0\;{aze.|addze.} %4,%3
8228 {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
8229 {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
8230 {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3"
b19003d8
RK
8231 [(set_attr "type" "compare")
8232 (set_attr "length" "12,8,12,12,12")])
1fd4e8c1
RK
8233
8234(define_insn ""
cd2b37d9 8235 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
deb9225a 8236 (neg:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1fd4e8c1
RK
8237 (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))))]
8238 ""
8239 "@
ca7f5001
RK
8240 xor %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
8241 {ai|addic} %0,%1,-1\;{sfe|subfe} %0,%0,%0
8242 {xoril|xori} %0,%1,%b2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
8243 {xoriu|xoris} %0,%1,%u2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
8244 {sfi|subfic} %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0"
b19003d8 8245 [(set_attr "length" "12,8,12,12,12")])
1fd4e8c1 8246
ea9be077
MM
8247;; Simplify (ne X (const_int 0)) on the PowerPC. No need to on the Power,
8248;; since it nabs/sr is just as fast.
8249(define_insn ""
8250 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8251 (lshiftrt:SI (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
8252 (const_int 31)))
8253 (clobber (match_scratch:SI 2 "=&r"))]
8254 "!TARGET_POWER"
8255 "{ai|addic} %2,%1,-1\;{sfe|subfe} %0,%2,%1"
8256 [(set_attr "length" "8")])
8257
1fd4e8c1
RK
8258;; This is what (plus (ne X (const_int 0)) Y) looks like.
8259(define_insn ""
cd2b37d9 8260 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1 8261 (plus:SI (lshiftrt:SI
cd2b37d9 8262 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
1fd4e8c1 8263 (const_int 31))
cd2b37d9 8264 (match_operand:SI 2 "gpc_reg_operand" "r")))
1fd4e8c1
RK
8265 (clobber (match_scratch:SI 3 "=&r"))]
8266 ""
ca7f5001 8267 "{ai|addic} %3,%1,-1\;{aze|addze} %0,%2"
b19003d8 8268 [(set_attr "length" "8")])
1fd4e8c1
RK
8269
8270(define_insn ""
8271 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
8272 (compare:CC
8273 (plus:SI (lshiftrt:SI
cd2b37d9 8274 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
1fd4e8c1 8275 (const_int 31))
cd2b37d9 8276 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1
RK
8277 (const_int 0)))
8278 (clobber (match_scratch:SI 3 "=&r"))]
8279 ""
ca7f5001 8280 "{ai|addic} %3,%1,-1\;{aze.|addze.} %3,%2"
b19003d8
RK
8281 [(set_attr "type" "compare")
8282 (set_attr "length" "8")])
1fd4e8c1
RK
8283
8284(define_insn ""
8285 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
8286 (compare:CC
8287 (plus:SI (lshiftrt:SI
cd2b37d9 8288 (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
1fd4e8c1 8289 (const_int 31))
cd2b37d9 8290 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 8291 (const_int 0)))
cd2b37d9 8292 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8293 (plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1))) (const_int 31))
8294 (match_dup 2)))
8295 (clobber (match_scratch:SI 3 "=&r"))]
8296 ""
ca7f5001 8297 "{ai|addic} %3,%1,-1\;{aze.|addze.} %0,%2"
b19003d8
RK
8298 [(set_attr "type" "compare")
8299 (set_attr "length" "8")])
1fd4e8c1
RK
8300
8301(define_insn ""
cd2b37d9
RK
8302 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8303 (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
8304 (match_operand:SI 2 "reg_or_short_operand" "r,O")))
8305 (clobber (match_scratch:SI 3 "=r,X"))]
ca7f5001 8306 "TARGET_POWER"
1fd4e8c1 8307 "@
ca7f5001 8308 doz %3,%2,%1\;{sfi|subfic} %0,%3,0\;{ae|adde} %0,%0,%3
7f340546 8309 {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{sri|srwi} %0,%0,31"
b19003d8 8310 [(set_attr "length" "12")])
1fd4e8c1
RK
8311
8312(define_insn ""
8313 [(set (match_operand:CC 4 "cc_reg_operand" "=x,x")
8314 (compare:CC
cd2b37d9 8315 (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
8316 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
8317 (const_int 0)))
cd2b37d9 8318 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
8319 (le:SI (match_dup 1) (match_dup 2)))
8320 (clobber (match_scratch:SI 3 "=r,X"))]
ca7f5001 8321 "TARGET_POWER"
1fd4e8c1 8322 "@
ca7f5001 8323 doz %3,%2,%1\;{sfi|subfic} %0,%3,0\;{ae.|adde.} %0,%0,%3
7f340546 8324 {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{sri.|srwi.} %0,%0,31"
a473029f 8325 [(set_attr "type" "compare,delayed_compare")
b19003d8 8326 (set_attr "length" "12")])
1fd4e8c1
RK
8327
8328(define_insn ""
cd2b37d9
RK
8329 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
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 8333 (clobber (match_scratch:SI 4 "=&r,&r"))]
ca7f5001 8334 "TARGET_POWER"
1fd4e8c1 8335 "@
ca7f5001
RK
8336 doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3
8337 {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze|addze} %0,%3"
b19003d8 8338 [(set_attr "length" "12")])
1fd4e8c1
RK
8339
8340(define_insn ""
8341 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
8342 (compare:CC
cd2b37d9 8343 (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 8344 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
cd2b37d9 8345 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1
RK
8346 (const_int 0)))
8347 (clobber (match_scratch:SI 4 "=&r,&r"))]
ca7f5001 8348 "TARGET_POWER"
1fd4e8c1 8349 "@
ca7f5001
RK
8350 doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
8351 {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze.|addze.} %4,%3"
b19003d8
RK
8352 [(set_attr "type" "compare")
8353 (set_attr "length" "12")])
1fd4e8c1
RK
8354
8355(define_insn ""
8356 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
8357 (compare:CC
cd2b37d9 8358 (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 8359 (match_operand:SI 2 "reg_or_short_operand" "r,O"))
cd2b37d9 8360 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 8361 (const_int 0)))
cd2b37d9 8362 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
8363 (plus:SI (le:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
8364 (clobber (match_scratch:SI 4 "=&r,&r"))]
ca7f5001 8365 "TARGET_POWER"
1fd4e8c1 8366 "@
ca7f5001
RK
8367 doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
8368 {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze.|addze.} %0,%3"
b19003d8
RK
8369 [(set_attr "type" "compare")
8370 (set_attr "length" "12")])
1fd4e8c1
RK
8371
8372(define_insn ""
cd2b37d9
RK
8373 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8374 (neg:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 8375 (match_operand:SI 2 "reg_or_short_operand" "r,O"))))]
ca7f5001 8376 "TARGET_POWER"
1fd4e8c1 8377 "@
ca7f5001
RK
8378 doz %0,%2,%1\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
8379 {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{srai|srawi} %0,%0,31"
b19003d8 8380 [(set_attr "length" "12")])
1fd4e8c1
RK
8381
8382(define_insn ""
cd2b37d9
RK
8383 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8384 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8385 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
8386 ""
ca7f5001 8387 "{sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0"
b19003d8 8388 [(set_attr "length" "12")])
1fd4e8c1
RK
8389
8390(define_insn ""
8391 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
8392 (compare:CC
cd2b37d9 8393 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8394 (match_operand:SI 2 "reg_or_short_operand" "rI"))
8395 (const_int 0)))
cd2b37d9 8396 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8397 (leu:SI (match_dup 1) (match_dup 2)))]
8398 ""
ca7f5001 8399 "{sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0"
b19003d8
RK
8400 [(set_attr "type" "compare")
8401 (set_attr "length" "12")])
1fd4e8c1
RK
8402
8403(define_insn ""
cd2b37d9
RK
8404 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8405 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8406 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 8407 (match_operand:SI 3 "gpc_reg_operand" "r")))
1fd4e8c1
RK
8408 (clobber (match_scratch:SI 4 "=&r"))]
8409 ""
ca7f5001 8410 "{sf%I2|subf%I2c} %4,%1,%2\;{aze|addze} %0,%3"
b19003d8 8411 [(set_attr "length" "8")])
1fd4e8c1
RK
8412
8413(define_insn ""
8414 [(set (match_operand:CC 0 "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
RK
8419 (const_int 0)))
8420 (clobber (match_scratch:SI 4 "=&r"))]
8421 ""
ca7f5001 8422 "{sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %4,%3"
b19003d8
RK
8423 [(set_attr "type" "compare")
8424 (set_attr "length" "8")])
1fd4e8c1
RK
8425
8426(define_insn ""
8427 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
8428 (compare:CC
cd2b37d9 8429 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8430 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 8431 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1 8432 (const_int 0)))
cd2b37d9 8433 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8434 (plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
8435 (clobber (match_scratch:SI 4 "=&r"))]
8436 ""
ca7f5001 8437 "{sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %0,%3"
b19003d8
RK
8438 [(set_attr "type" "compare")
8439 (set_attr "length" "8")])
1fd4e8c1
RK
8440
8441(define_insn ""
cd2b37d9
RK
8442 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8443 (neg:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8444 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
8445 ""
ca7f5001 8446 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;nand %0,%0,%0"
b19003d8 8447 [(set_attr "length" "12")])
1fd4e8c1
RK
8448
8449(define_insn ""
cd2b37d9 8450 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1 8451 (and:SI (neg:SI
cd2b37d9 8452 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8453 (match_operand:SI 2 "reg_or_short_operand" "rI")))
cd2b37d9 8454 (match_operand:SI 3 "gpc_reg_operand" "r")))
1fd4e8c1
RK
8455 (clobber (match_scratch:SI 4 "=&r"))]
8456 ""
ca7f5001 8457 "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4"
b19003d8 8458 [(set_attr "length" "12")])
1fd4e8c1
RK
8459
8460(define_insn ""
8461 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
8462 (compare:CC
8463 (and:SI (neg:SI
cd2b37d9 8464 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8465 (match_operand:SI 2 "reg_or_short_operand" "rI")))
cd2b37d9 8466 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1
RK
8467 (const_int 0)))
8468 (clobber (match_scratch:SI 4 "=&r"))]
8469 ""
ca7f5001 8470 "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4"
b19003d8
RK
8471 [(set_attr "type" "compare")
8472 (set_attr "length" "12")])
1fd4e8c1
RK
8473
8474(define_insn ""
8475 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
8476 (compare:CC
8477 (and:SI (neg:SI
cd2b37d9 8478 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8479 (match_operand:SI 2 "reg_or_short_operand" "rI")))
cd2b37d9 8480 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1 8481 (const_int 0)))
cd2b37d9 8482 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8483 (and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))
8484 (clobber (match_scratch:SI 4 "=&r"))]
8485 ""
ca7f5001 8486 "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4"
b19003d8
RK
8487 [(set_attr "type" "compare")
8488 (set_attr "length" "12")])
1fd4e8c1
RK
8489
8490(define_insn ""
cd2b37d9
RK
8491 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8492 (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8493 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
ca7f5001 8494 "TARGET_POWER"
7f340546 8495 "doz%I2 %0,%1,%2\;nabs %0,%0\;{sri|srwi} %0,%0,31"
b19003d8 8496 [(set_attr "length" "12")])
1fd4e8c1
RK
8497
8498(define_insn ""
ad8bd902 8499 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1fd4e8c1 8500 (compare:CC
cd2b37d9 8501 (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8502 (match_operand:SI 2 "reg_or_short_operand" "rI"))
8503 (const_int 0)))
cd2b37d9 8504 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1 8505 (lt:SI (match_dup 1) (match_dup 2)))]
ca7f5001 8506 "TARGET_POWER"
7f340546 8507 "doz%I2 %0,%1,%2\;nabs %0,%0\;{sri.|srwi.} %0,%0,31"
b19003d8
RK
8508 [(set_attr "type" "delayed_compare")
8509 (set_attr "length" "12")])
1fd4e8c1
RK
8510
8511(define_insn ""
cd2b37d9
RK
8512 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8513 (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8514 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 8515 (match_operand:SI 3 "gpc_reg_operand" "r")))
1fd4e8c1 8516 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
8517 "TARGET_POWER"
8518 "doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze|addze} %0,%3"
b19003d8 8519 [(set_attr "length" "12")])
1fd4e8c1
RK
8520
8521(define_insn ""
ad8bd902 8522 [(set (match_operand:CC 0 "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
RK
8527 (const_int 0)))
8528 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
8529 "TARGET_POWER"
8530 "doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze.|addze.} %4,%3"
b19003d8
RK
8531 [(set_attr "type" "compare")
8532 (set_attr "length" "12")])
1fd4e8c1
RK
8533
8534(define_insn ""
ad8bd902 8535 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
1fd4e8c1 8536 (compare:CC
cd2b37d9 8537 (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8538 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 8539 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1 8540 (const_int 0)))
cd2b37d9 8541 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8542 (plus:SI (lt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
8543 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
8544 "TARGET_POWER"
8545 "doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze.|addze.} %0,%3"
b19003d8
RK
8546 [(set_attr "type" "compare")
8547 (set_attr "length" "12")])
1fd4e8c1
RK
8548
8549(define_insn ""
cd2b37d9
RK
8550 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8551 (neg:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8552 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
ca7f5001
RK
8553 "TARGET_POWER"
8554 "doz%I2 %0,%1,%2\;nabs %0,%0\;{srai|srawi} %0,%0,31"
b19003d8 8555 [(set_attr "length" "12")])
1fd4e8c1
RK
8556
8557(define_insn ""
cd2b37d9
RK
8558 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8559 (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
8560 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))]
8561 ""
8562 "@
ca7f5001
RK
8563 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg %0,%0
8564 {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg %0,%0"
b19003d8 8565 [(set_attr "length" "12")])
1fd4e8c1
RK
8566
8567(define_insn ""
8568 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
8569 (compare:CC
cd2b37d9 8570 (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
8571 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
8572 (const_int 0)))
cd2b37d9 8573 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
8574 (ltu:SI (match_dup 1) (match_dup 2)))]
8575 ""
8576 "@
ca7f5001
RK
8577 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg. %0,%0
8578 {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0"
b19003d8
RK
8579 [(set_attr "type" "compare")
8580 (set_attr "length" "12")])
1fd4e8c1
RK
8581
8582(define_insn ""
cd2b37d9
RK
8583 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
8584 (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
1fd4e8c1
RK
8585 (match_operand:SI 2 "reg_or_neg_short_operand" "r,r,P,P"))
8586 (match_operand:SI 3 "reg_or_short_operand" "r,I,r,I")))
8587 (clobber (match_scratch:SI 4 "=&r,r,&r,r"))]
8588 ""
8589 "@
ca7f5001
RK
8590 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
8591 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
8592 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
8593 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3"
b19003d8 8594 [(set_attr "length" "12")])
1fd4e8c1
RK
8595
8596(define_insn ""
3d91674b 8597 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
1fd4e8c1 8598 (compare:CC
3d91674b
RK
8599 (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
8600 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
8601 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 8602 (const_int 0)))
3d91674b 8603 (clobber (match_scratch:SI 4 "=&r,&r"))]
1fd4e8c1
RK
8604 ""
8605 "@
ca7f5001
RK
8606 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3
8607 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3"
b19003d8
RK
8608 [(set_attr "type" "compare")
8609 (set_attr "length" "12")])
1fd4e8c1
RK
8610
8611(define_insn ""
3d91674b 8612 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
1fd4e8c1 8613 (compare:CC
3d91674b
RK
8614 (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
8615 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
8616 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 8617 (const_int 0)))
3d91674b 8618 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1 8619 (plus:SI (ltu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
3d91674b 8620 (clobber (match_scratch:SI 4 "=&r,&r"))]
1fd4e8c1
RK
8621 ""
8622 "@
ca7f5001
RK
8623 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3
8624 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3"
b19003d8
RK
8625 [(set_attr "type" "compare")
8626 (set_attr "length" "12")])
1fd4e8c1
RK
8627
8628(define_insn ""
cd2b37d9
RK
8629 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8630 (neg:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
8631 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))))]
8632 ""
8633 "@
ca7f5001
RK
8634 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0
8635 {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0"
b19003d8 8636 [(set_attr "length" "8")])
1fd4e8c1
RK
8637
8638(define_insn ""
cd2b37d9
RK
8639 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8640 (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8641 (match_operand:SI 2 "reg_or_short_operand" "rI")))
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 8645 [(set_attr "length" "12")])
1fd4e8c1
RK
8646
8647(define_insn ""
8648 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
8649 (compare:CC
cd2b37d9 8650 (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8651 (match_operand:SI 2 "reg_or_short_operand" "rI"))
8652 (const_int 0)))
cd2b37d9 8653 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8654 (ge:SI (match_dup 1) (match_dup 2)))
8655 (clobber (match_scratch:SI 3 "=r"))]
ca7f5001
RK
8656 "TARGET_POWER"
8657 "doz%I2 %3,%1,%2\;{sfi|subfic} %0,%3,0\;{ae.|adde.} %0,%0,%3"
b19003d8
RK
8658 [(set_attr "type" "compare")
8659 (set_attr "length" "12")])
1fd4e8c1
RK
8660
8661(define_insn ""
cd2b37d9
RK
8662 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8663 (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8664 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 8665 (match_operand:SI 3 "gpc_reg_operand" "r")))
1fd4e8c1 8666 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
8667 "TARGET_POWER"
8668 "doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3"
b19003d8 8669 [(set_attr "length" "12")])
1fd4e8c1
RK
8670
8671(define_insn ""
8672 [(set (match_operand:CC 0 "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
RK
8677 (const_int 0)))
8678 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
8679 "TARGET_POWER"
8680 "doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3"
b19003d8
RK
8681 [(set_attr "type" "compare")
8682 (set_attr "length" "12")])
1fd4e8c1
RK
8683
8684(define_insn ""
8685 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
8686 (compare:CC
cd2b37d9 8687 (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8688 (match_operand:SI 2 "reg_or_short_operand" "rI"))
cd2b37d9 8689 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1 8690 (const_int 0)))
cd2b37d9 8691 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8692 (plus:SI (ge:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
8693 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
8694 "TARGET_POWER"
8695 "doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3"
b19003d8
RK
8696 [(set_attr "type" "compare")
8697 (set_attr "length" "12")])
1fd4e8c1
RK
8698
8699(define_insn ""
cd2b37d9
RK
8700 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8701 (neg:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8702 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
ca7f5001
RK
8703 "TARGET_POWER"
8704 "doz%I2 %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0"
b19003d8 8705 [(set_attr "length" "12")])
1fd4e8c1
RK
8706
8707;; This is (and (neg (ge X (const_int 0))) Y).
8708(define_insn ""
cd2b37d9 8709 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
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 (clobber (match_scratch:SI 3 "=&r"))]
8716 ""
ca7f5001 8717 "{srai|srawi} %3,%1,31\;andc %0,%2,%3"
b19003d8 8718 [(set_attr "length" "8")])
1fd4e8c1
RK
8719
8720(define_insn ""
8721 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
8722 (compare:CC
8723 (and:SI (neg:SI
8724 (lshiftrt:SI
cd2b37d9 8725 (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1fd4e8c1 8726 (const_int 31)))
cd2b37d9 8727 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1
RK
8728 (const_int 0)))
8729 (clobber (match_scratch:SI 3 "=&r"))]
8730 ""
ca7f5001 8731 "{srai|srawi} %3,%1,31\;andc. %3,%2,%3"
b19003d8
RK
8732 [(set_attr "type" "compare")
8733 (set_attr "length" "8")])
1fd4e8c1
RK
8734
8735(define_insn ""
8736 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
8737 (compare:CC
8738 (and:SI (neg:SI
8739 (lshiftrt:SI
cd2b37d9 8740 (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
1fd4e8c1 8741 (const_int 31)))
cd2b37d9 8742 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 8743 (const_int 0)))
cd2b37d9 8744 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8745 (and:SI (neg:SI (lshiftrt:SI (not:SI (match_dup 1))
8746 (const_int 31)))
8747 (match_dup 2)))
8748 (clobber (match_scratch:SI 3 "=&r"))]
8749 ""
ca7f5001 8750 "{srai|srawi} %3,%1,31\;andc. %0,%2,%3"
b19003d8
RK
8751 [(set_attr "type" "compare")
8752 (set_attr "length" "8")])
1fd4e8c1
RK
8753
8754(define_insn ""
cd2b37d9
RK
8755 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8756 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
8757 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))]
8758 ""
8759 "@
ca7f5001
RK
8760 {sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0
8761 {ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0"
b19003d8 8762 [(set_attr "length" "12")])
1fd4e8c1
RK
8763
8764(define_insn ""
8765 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
8766 (compare:CC
cd2b37d9 8767 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
8768 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
8769 (const_int 0)))
cd2b37d9 8770 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
8771 (geu:SI (match_dup 1) (match_dup 2)))]
8772 ""
8773 "@
ca7f5001
RK
8774 {sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0
8775 {ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0"
b19003d8
RK
8776 [(set_attr "type" "compare")
8777 (set_attr "length" "12")])
1fd4e8c1
RK
8778
8779(define_insn ""
cd2b37d9
RK
8780 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
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 (clobber (match_scratch:SI 4 "=&r,&r"))]
8785 ""
8786 "@
ca7f5001
RK
8787 {sf|subfc} %4,%2,%1\;{aze|addze} %0,%3
8788 {ai|addic} %4,%1,%n2\;{aze|addze} %0,%3"
b19003d8 8789 [(set_attr "length" "8")])
1fd4e8c1
RK
8790
8791(define_insn ""
8792 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
8793 (compare:CC
cd2b37d9 8794 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 8795 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
cd2b37d9 8796 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1
RK
8797 (const_int 0)))
8798 (clobber (match_scratch:SI 4 "=&r,&r"))]
8799 ""
8800 "@
ca7f5001
RK
8801 {sf|subfc} %4,%2,%1\;{aze.|addze.} %4,%3
8802 {ai|addic} %4,%1,%n2\;{aze.|addze.} %4,%3"
b19003d8
RK
8803 [(set_attr "type" "compare")
8804 (set_attr "length" "8")])
1fd4e8c1
RK
8805
8806(define_insn ""
8807 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
8808 (compare:CC
cd2b37d9 8809 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 8810 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
cd2b37d9 8811 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 8812 (const_int 0)))
cd2b37d9 8813 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
8814 (plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
8815 (clobber (match_scratch:SI 4 "=&r,&r"))]
8816 ""
8817 "@
ca7f5001
RK
8818 {sf|subfc} %4,%2,%1\;{aze.|addze.} %0,%3
8819 {ai|addic} %4,%1,%n2\;{aze.|addze.} %4,%3"
b19003d8
RK
8820 [(set_attr "type" "compare")
8821 (set_attr "length" "8")])
1fd4e8c1
RK
8822
8823(define_insn ""
cd2b37d9
RK
8824 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
8825 (neg:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1
RK
8826 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))]
8827 ""
8828 "@
ca7f5001 8829 {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;nand %0,%0,%0
8106dc08 8830 {sfi|subfic} %0,%1,-1\;{a%I2|add%I2c} %0,%0,%2\;{sfe|subfe} %0,%0,%0"
b19003d8 8831 [(set_attr "length" "12")])
1fd4e8c1
RK
8832
8833(define_insn ""
cd2b37d9 8834 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1 8835 (and:SI (neg:SI
cd2b37d9 8836 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 8837 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))
cd2b37d9 8838 (match_operand:SI 3 "gpc_reg_operand" "r,r")))
1fd4e8c1
RK
8839 (clobber (match_scratch:SI 4 "=&r,&r"))]
8840 ""
8841 "@
ca7f5001
RK
8842 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4
8843 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4"
b19003d8 8844 [(set_attr "length" "12")])
1fd4e8c1
RK
8845
8846(define_insn ""
8847 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
8848 (compare:CC
8849 (and:SI (neg:SI
cd2b37d9 8850 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 8851 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))
cd2b37d9 8852 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1
RK
8853 (const_int 0)))
8854 (clobber (match_scratch:SI 4 "=&r,&r"))]
8855 ""
8856 "@
ca7f5001
RK
8857 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4
8858 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4"
b19003d8
RK
8859 [(set_attr "type" "compare")
8860 (set_attr "length" "12")])
1fd4e8c1
RK
8861
8862(define_insn ""
8863 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
8864 (compare:CC
8865 (and:SI (neg:SI
cd2b37d9 8866 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1fd4e8c1 8867 (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))
cd2b37d9 8868 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 8869 (const_int 0)))
cd2b37d9 8870 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1
RK
8871 (and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))
8872 (clobber (match_scratch:SI 4 "=&r,&r"))]
8873 ""
8874 "@
ca7f5001
RK
8875 {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4
8876 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4"
b19003d8
RK
8877 [(set_attr "type" "compare")
8878 (set_attr "length" "12")])
1fd4e8c1
RK
8879
8880(define_insn ""
cd2b37d9
RK
8881 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8882 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8883 (const_int 0)))]
8884 ""
ca7f5001 8885 "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri|srwi} %0,%0,31"
b19003d8 8886 [(set_attr "length" "12")])
1fd4e8c1
RK
8887
8888(define_insn ""
8889 [(set (match_operand:CC 2 "cc_reg_operand" "=x")
8890 (compare:CC
cd2b37d9 8891 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8892 (const_int 0))
8893 (const_int 0)))
cd2b37d9 8894 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8895 (gt:SI (match_dup 1) (const_int 0)))]
8896 ""
ca7f5001 8897 "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri.|srwi.} %0,%0,31"
b19003d8
RK
8898 [(set_attr "type" "delayed_compare")
8899 (set_attr "length" "12")])
1fd4e8c1
RK
8900
8901(define_insn ""
cd2b37d9
RK
8902 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8903 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8904 (match_operand:SI 2 "reg_or_short_operand" "r")))]
ca7f5001
RK
8905 "TARGET_POWER"
8906 "doz %0,%2,%1\;nabs %0,%0\;{sri|srwi} %0,%0,31"
b19003d8 8907 [(set_attr "length" "12")])
1fd4e8c1
RK
8908
8909(define_insn ""
8910 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
8911 (compare:CC
cd2b37d9 8912 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
8913 (match_operand:SI 2 "reg_or_short_operand" "r"))
8914 (const_int 0)))
cd2b37d9 8915 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1 8916 (gt:SI (match_dup 1) (match_dup 2)))]
ca7f5001
RK
8917 "TARGET_POWER"
8918 "doz %0,%2,%1\;nabs %0,%0\;{sri.|srwi.} %0,%0,31"
b19003d8
RK
8919 [(set_attr "type" "delayed_compare")
8920 (set_attr "length" "12")])
1fd4e8c1
RK
8921
8922(define_insn ""
cd2b37d9
RK
8923 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8924 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8925 (const_int 0))
cd2b37d9 8926 (match_operand:SI 2 "gpc_reg_operand" "r")))
1fd4e8c1
RK
8927 (clobber (match_scratch:SI 3 "=&r"))]
8928 ""
ca7f5001 8929 "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze|addze} %0,%2"
b19003d8 8930 [(set_attr "length" "12")])
1fd4e8c1
RK
8931
8932(define_insn ""
8933 [(set (match_operand:CC 0 "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
RK
8938 (const_int 0)))
8939 (clobber (match_scratch:SI 3 "=&r"))]
8940 ""
ca7f5001 8941 "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %0,%2"
b19003d8
RK
8942 [(set_attr "type" "compare")
8943 (set_attr "length" "12")])
1fd4e8c1
RK
8944
8945(define_insn ""
8946 [(set (match_operand:CC 4 "cc_reg_operand" "=x")
8947 (compare:CC
cd2b37d9 8948 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8949 (const_int 0))
cd2b37d9 8950 (match_operand:SI 2 "gpc_reg_operand" "r"))
1fd4e8c1 8951 (const_int 0)))
cd2b37d9 8952 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8953 (plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2)))
8954 (clobber (match_scratch:SI 3 "=&r"))]
8955 ""
ca7f5001 8956 "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %3,%2"
b19003d8
RK
8957 [(set_attr "type" "compare")
8958 (set_attr "length" "12")])
1fd4e8c1
RK
8959
8960(define_insn ""
cd2b37d9
RK
8961 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8962 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8963 (match_operand:SI 2 "reg_or_short_operand" "r"))
cd2b37d9 8964 (match_operand:SI 3 "gpc_reg_operand" "r")))
1fd4e8c1 8965 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
8966 "TARGET_POWER"
8967 "doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze|addze} %0,%3"
b19003d8 8968 [(set_attr "length" "12")])
1fd4e8c1
RK
8969
8970(define_insn ""
8971 [(set (match_operand:CC 0 "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
RK
8976 (const_int 0)))
8977 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
8978 "TARGET_POWER"
8979 "doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze.|addze.} %4,%3"
b19003d8
RK
8980 [(set_attr "type" "compare")
8981 (set_attr "length" "12")])
1fd4e8c1
RK
8982
8983(define_insn ""
8984 [(set (match_operand:CC 5 "cc_reg_operand" "=x")
8985 (compare:CC
cd2b37d9 8986 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 8987 (match_operand:SI 2 "reg_or_short_operand" "r"))
cd2b37d9 8988 (match_operand:SI 3 "gpc_reg_operand" "r"))
1fd4e8c1 8989 (const_int 0)))
cd2b37d9 8990 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
8991 (plus:SI (gt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
8992 (clobber (match_scratch:SI 4 "=&r"))]
ca7f5001
RK
8993 "TARGET_POWER"
8994 "doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze.|addze.} %0,%3"
b19003d8
RK
8995 [(set_attr "type" "compare")
8996 (set_attr "length" "12")])
1fd4e8c1
RK
8997
8998(define_insn ""
cd2b37d9
RK
8999 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9000 (neg:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
9001 (const_int 0))))]
9002 ""
ca7f5001 9003 "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{srai|srawi} %0,%0,31"
b19003d8 9004 [(set_attr "length" "12")])
1fd4e8c1
RK
9005
9006(define_insn ""
cd2b37d9
RK
9007 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9008 (neg:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1 9009 (match_operand:SI 2 "reg_or_short_operand" "r"))))]
ca7f5001
RK
9010 "TARGET_POWER"
9011 "doz %0,%2,%1\;nabs %0,%0\;{srai|srawi} %0,%0,31"
b19003d8 9012 [(set_attr "length" "12")])
1fd4e8c1
RK
9013
9014(define_insn ""
cd2b37d9
RK
9015 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9016 (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
9017 (match_operand:SI 2 "reg_or_short_operand" "rI")))]
9018 ""
ca7f5001 9019 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg %0,%0"
b19003d8 9020 [(set_attr "length" "12")])
1fd4e8c1
RK
9021
9022(define_insn ""
9023 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
9024 (compare:CC
cd2b37d9 9025 (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
9026 (match_operand:SI 2 "reg_or_short_operand" "rI"))
9027 (const_int 0)))
cd2b37d9 9028 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1fd4e8c1
RK
9029 (gtu:SI (match_dup 1) (match_dup 2)))]
9030 ""
ca7f5001 9031 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0"
b19003d8
RK
9032 [(set_attr "type" "compare")
9033 (set_attr "length" "12")])
1fd4e8c1
RK
9034
9035(define_insn ""
00751805
RK
9036 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
9037 (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r")
9038 (match_operand:SI 2 "reg_or_short_operand" "I,r,rI"))
9039 (match_operand:SI 3 "reg_or_short_operand" "r,r,I")))
9040 (clobber (match_scratch:SI 4 "=&r,&r,&r"))]
1fd4e8c1 9041 ""
00751805 9042 "@
ca7f5001
RK
9043 {ai|addic} %4,%1,%k2\;{aze|addze} %0,%3
9044 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
9045 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3"
b19003d8 9046 [(set_attr "length" "8,12,12")])
1fd4e8c1
RK
9047
9048(define_insn ""
3d91674b 9049 [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
1fd4e8c1 9050 (compare:CC
3d91674b
RK
9051 (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
9052 (match_operand:SI 2 "reg_or_short_operand" "I,r"))
9053 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 9054 (const_int 0)))
3d91674b 9055 (clobber (match_scratch:SI 4 "=&r,&r"))]
1fd4e8c1 9056 ""
00751805 9057 "@
ca7f5001
RK
9058 {ai|addic} %4,%1,%k2\;{aze.|addze.} %0,%3
9059 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3"
b19003d8 9060 [(set_attr "type" "compare")
3d91674b 9061 (set_attr "length" "8,12")])
1fd4e8c1
RK
9062
9063(define_insn ""
3d91674b 9064 [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
1fd4e8c1 9065 (compare:CC
3d91674b
RK
9066 (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
9067 (match_operand:SI 2 "reg_or_short_operand" "I,r"))
9068 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1fd4e8c1 9069 (const_int 0)))
3d91674b 9070 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1fd4e8c1 9071 (plus:SI (gtu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
3d91674b 9072 (clobber (match_scratch:SI 4 "=&r,&r"))]
1fd4e8c1 9073 ""
00751805 9074 "@
ca7f5001
RK
9075 {ai|addic} %4,%1,%k2\;{aze.|addze.} %0,%3
9076 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3"
b19003d8 9077 [(set_attr "type" "compare")
3d91674b 9078 (set_attr "length" "8,12")])
1fd4e8c1
RK
9079
9080(define_insn ""
cd2b37d9
RK
9081 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9082 (neg:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1fd4e8c1
RK
9083 (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
9084 ""
ca7f5001 9085 "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0"
b19003d8 9086 [(set_attr "length" "8")])
1fd4e8c1
RK
9087\f
9088;; Define both directions of branch and return. If we need a reload
9089;; register, we'd rather use CR0 since it is much easier to copy a
9090;; register CC value to there.
9091
9092(define_insn ""
9093 [(set (pc)
9094 (if_then_else (match_operator 1 "branch_comparison_operator"
9095 [(match_operand 2
9096 "cc_reg_operand" "x,?y")
9097 (const_int 0)])
9098 (label_ref (match_operand 0 "" ""))
9099 (pc)))]
9100 ""
b19003d8
RK
9101 "*
9102{
9103 if (get_attr_length (insn) == 8)
9104 return \"%C1bc %t1,%j1,%l0\";
9105 else
c81bebd7
MM
9106 return \"%C1bc %T1,%j1,%$+8\;b %l0\";
9107
b19003d8
RK
9108}"
9109 [(set_attr "type" "branch")])
9110
1fd4e8c1
RK
9111(define_insn ""
9112 [(set (pc)
9113 (if_then_else (match_operator 0 "branch_comparison_operator"
9114 [(match_operand 1
9115 "cc_reg_operand" "x,?y")
9116 (const_int 0)])
9117 (return)
9118 (pc)))]
9119 "direct_return ()"
ca7f5001 9120 "{%C0bcr|%C0bclr} %t0,%j0"
b7ff3d82
DE
9121 [(set_attr "type" "branch")
9122 (set_attr "length" "8")])
1fd4e8c1
RK
9123
9124(define_insn ""
9125 [(set (pc)
9126 (if_then_else (match_operator 1 "branch_comparison_operator"
9127 [(match_operand 2
9128 "cc_reg_operand" "x,?y")
9129 (const_int 0)])
9130 (pc)
9131 (label_ref (match_operand 0 "" ""))))]
9132 ""
b19003d8
RK
9133 "*
9134{
9135 if (get_attr_length (insn) == 8)
9136 return \"%C1bc %T1,%j1,%l0\";
9137 else
c81bebd7 9138 return \"%C1bc %t1,%j1,%$+8\;b %l0\";
b19003d8
RK
9139}"
9140 [(set_attr "type" "branch")])
1fd4e8c1
RK
9141
9142(define_insn ""
9143 [(set (pc)
9144 (if_then_else (match_operator 0 "branch_comparison_operator"
9145 [(match_operand 1
9146 "cc_reg_operand" "x,?y")
9147 (const_int 0)])
9148 (pc)
9149 (return)))]
9150 "direct_return ()"
ca7f5001 9151 "{%C0bcr|%C0bclr} %T0,%j0"
b7ff3d82
DE
9152 [(set_attr "type" "branch")
9153 (set_attr "length" "8")])
1fd4e8c1
RK
9154
9155;; Unconditional branch and return.
9156
9157(define_insn "jump"
9158 [(set (pc)
9159 (label_ref (match_operand 0 "" "")))]
9160 ""
b7ff3d82
DE
9161 "b %l0"
9162 [(set_attr "type" "branch")])
1fd4e8c1
RK
9163
9164(define_insn "return"
9165 [(return)]
9166 "direct_return ()"
324e52cc
TG
9167 "{br|blr}"
9168 [(set_attr "type" "jmpreg")])
1fd4e8c1
RK
9169
9170(define_insn "indirect_jump"
9171 [(set (pc) (match_operand:SI 0 "register_operand" "c,l"))]
9172 ""
9173 "@
9174 bctr
324e52cc
TG
9175 {br|blr}"
9176 [(set_attr "type" "jmpreg")])
1fd4e8c1 9177
266eb58a
DE
9178(define_insn ""
9179 [(set (pc) (match_operand:DI 0 "register_operand" "c,l"))]
9180 "TARGET_POWERPC64"
9181 "@
9182 bctr
9183 {br|blr}"
9184 [(set_attr "type" "jmpreg")])
9185
1fd4e8c1
RK
9186;; Table jump for switch statements:
9187(define_expand "tablejump"
e6ca2c17
DE
9188 [(use (match_operand 0 "" ""))
9189 (use (label_ref (match_operand 1 "" "")))]
9190 ""
9191 "
9192{
9193 if (TARGET_32BIT)
9194 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
9195 else
9196 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
9197 DONE;
9198}")
9199
9200(define_expand "tablejumpsi"
1fd4e8c1
RK
9201 [(set (match_dup 3)
9202 (plus:SI (match_operand:SI 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 (SImode, operands[0]);
9209 operands[2] = force_reg (SImode, gen_rtx (LABEL_REF, VOIDmode, operands[1]));
9210 operands[3] = gen_reg_rtx (SImode);
9211}")
9212
e6ca2c17
DE
9213(define_expand "tablejumpdi"
9214 [(set (match_dup 3)
9215 (plus:DI (match_operand:DI 0 "" "")
9216 (match_dup 2)))
9217 (parallel [(set (pc) (match_dup 3))
9218 (use (label_ref (match_operand 1 "" "")))])]
9219 ""
9220 "
9221{ operands[0] = force_reg (DImode, operands[0]);
9222 operands[2] = force_reg (DImode, gen_rtx (LABEL_REF, VOIDmode, operands[1]));
9223 operands[3] = gen_reg_rtx (DImode);
9224}")
9225
1fd4e8c1
RK
9226(define_insn ""
9227 [(set (pc)
740ab4a2 9228 (match_operand:SI 0 "register_operand" "c,l"))
1fd4e8c1
RK
9229 (use (label_ref (match_operand 1 "" "")))]
9230 ""
9231 "@
9232 bctr
a6845123
RK
9233 {br|blr}"
9234 [(set_attr "type" "jmpreg")])
1fd4e8c1 9235
266eb58a
DE
9236(define_insn ""
9237 [(set (pc)
9238 (match_operand:DI 0 "register_operand" "c,l"))
9239 (use (label_ref (match_operand 1 "" "")))]
9240 "TARGET_POWERPC64"
9241 "@
9242 bctr
9243 {br|blr}"
9244 [(set_attr "type" "jmpreg")])
9245
1fd4e8c1
RK
9246(define_insn "nop"
9247 [(const_int 0)]
9248 ""
ca7f5001 9249 "{cror 0,0,0|nop}")
1fd4e8c1 9250\f
7e69e155 9251;; Define the subtract-one-and-jump insns, starting with the template
c225ba7b
RK
9252;; so loop.c knows what to generate.
9253
b6c9286a
MM
9254(define_expand "decrement_and_branch_on_count"
9255 [(parallel [(set (pc) (if_then_else (ne (match_operand:SI 0 "register_operand" "")
c225ba7b
RK
9256 (const_int 1))
9257 (label_ref (match_operand 1 "" ""))
9258 (pc)))
b6c9286a
MM
9259 (set (match_dup 0)
9260 (plus:SI (match_dup 0)
9261 (const_int -1)))
5f81043f
RK
9262 (clobber (match_scratch:CC 2 ""))
9263 (clobber (match_scratch:SI 3 ""))])]
c225ba7b
RK
9264 ""
9265 "")
9266
1fd4e8c1
RK
9267;; We need to be able to do this for any operand, including MEM, or we
9268;; will cause reload to blow up since we don't allow output reloads on
7e69e155 9269;; JUMP_INSNs.
5f81043f
RK
9270;; In order that the length attribute is calculated correctly, the
9271;; label MUST be operand 0.
9272
1fd4e8c1
RK
9273(define_insn ""
9274 [(set (pc)
5f81043f 9275 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,*r,*r")
1fd4e8c1 9276 (const_int 1))
a6845123 9277 (label_ref (match_operand 0 "" ""))
1fd4e8c1 9278 (pc)))
5f81043f
RK
9279 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
9280 (plus:SI (match_dup 1)
9281 (const_int -1)))
1fd4e8c1
RK
9282 (clobber (match_scratch:CC 3 "=X,&x,&x"))
9283 (clobber (match_scratch:SI 4 "=X,X,r"))]
9284 ""
b19003d8
RK
9285 "*
9286{
af87a13e 9287 if (which_alternative != 0)
b19003d8
RK
9288 return \"#\";
9289 else if (get_attr_length (insn) == 8)
a6845123 9290 return \"{bdn|bdnz} %l0\";
b19003d8 9291 else
c81bebd7 9292 return \"bdz %$+8\;b %l0\";
b19003d8 9293}"
baf97f86
RK
9294 [(set_attr "type" "branch")
9295 (set_attr "length" "*,12,16")])
7e69e155 9296
5f81043f
RK
9297(define_insn ""
9298 [(set (pc)
9299 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,*r,*r")
9300 (const_int 1))
9301 (pc)
9302 (label_ref (match_operand 0 "" ""))))
9303 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
9304 (plus:SI (match_dup 1)
9305 (const_int -1)))
9306 (clobber (match_scratch:CC 3 "=X,&x,&x"))
9307 (clobber (match_scratch:SI 4 "=X,X,r"))]
9308 ""
9309 "*
9310{
9311 if (which_alternative != 0)
9312 return \"#\";
9313 else if (get_attr_length (insn) == 8)
9314 return \"bdz %l0\";
9315 else
c81bebd7 9316 return \"{bdn|bdnz} %$+8\;b %l0\";
5f81043f
RK
9317}"
9318 [(set_attr "type" "branch")
9319 (set_attr "length" "*,12,16")])
9320
c225ba7b 9321;; Similar, but we can use GE since we have a REG_NONNEG.
1fd4e8c1
RK
9322(define_insn ""
9323 [(set (pc)
5f81043f 9324 (if_then_else (ge (match_operand:SI 1 "register_operand" "c,*r,*r")
1fd4e8c1 9325 (const_int 0))
a6845123 9326 (label_ref (match_operand 0 "" ""))
1fd4e8c1 9327 (pc)))
5f81043f
RK
9328 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
9329 (plus:SI (match_dup 1)
9330 (const_int -1)))
1fd4e8c1
RK
9331 (clobber (match_scratch:CC 3 "=X,&x,&X"))
9332 (clobber (match_scratch:SI 4 "=X,X,r"))]
9333 "find_reg_note (insn, REG_NONNEG, 0)"
b19003d8
RK
9334 "*
9335{
af87a13e 9336 if (which_alternative != 0)
b19003d8
RK
9337 return \"#\";
9338 else if (get_attr_length (insn) == 8)
a6845123 9339 return \"{bdn|bdnz} %l0\";
b19003d8 9340 else
c81bebd7 9341 return \"bdz %$+8\;b %l0\";
b19003d8 9342}"
baf97f86
RK
9343 [(set_attr "type" "branch")
9344 (set_attr "length" "*,12,16")])
7e69e155 9345
1fd4e8c1
RK
9346(define_insn ""
9347 [(set (pc)
5f81043f
RK
9348 (if_then_else (ge (match_operand:SI 1 "register_operand" "c,*r,*r")
9349 (const_int 0))
9350 (pc)
9351 (label_ref (match_operand 0 "" ""))))
9352 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
9353 (plus:SI (match_dup 1)
9354 (const_int -1)))
9355 (clobber (match_scratch:CC 3 "=X,&x,&X"))
9356 (clobber (match_scratch:SI 4 "=X,X,r"))]
9357 "find_reg_note (insn, REG_NONNEG, 0)"
9358 "*
9359{
9360 if (which_alternative != 0)
9361 return \"#\";
9362 else if (get_attr_length (insn) == 8)
9363 return \"bdz %l0\";
9364 else
c81bebd7 9365 return \"{bdn|bdnz} %$+8\;b %l0\";
5f81043f
RK
9366}"
9367 [(set_attr "type" "branch")
9368 (set_attr "length" "*,12,16")])
9369
9370(define_insn ""
9371 [(set (pc)
9372 (if_then_else (eq (match_operand:SI 1 "register_operand" "c,*r,*r")
1fd4e8c1 9373 (const_int 1))
a6845123 9374 (label_ref (match_operand 0 "" ""))
1fd4e8c1 9375 (pc)))
5f81043f
RK
9376 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
9377 (plus:SI (match_dup 1)
9378 (const_int -1)))
1fd4e8c1
RK
9379 (clobber (match_scratch:CC 3 "=X,&x,&x"))
9380 (clobber (match_scratch:SI 4 "=X,X,r"))]
9381 ""
b19003d8
RK
9382 "*
9383{
af87a13e 9384 if (which_alternative != 0)
b19003d8
RK
9385 return \"#\";
9386 else if (get_attr_length (insn) == 8)
a6845123 9387 return \"bdz %l0\";
b19003d8 9388 else
c81bebd7 9389 return \"{bdn|bdnz} %$+8\;b %l0\";
b19003d8 9390}"
baf97f86
RK
9391 [(set_attr "type" "branch")
9392 (set_attr "length" "*,12,16")])
1fd4e8c1 9393
5f81043f
RK
9394(define_insn ""
9395 [(set (pc)
9396 (if_then_else (eq (match_operand:SI 1 "register_operand" "c,*r,*r")
9397 (const_int 1))
9398 (pc)
9399 (label_ref (match_operand 0 "" ""))))
9400 (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
9401 (plus:SI (match_dup 1)
9402 (const_int -1)))
9403 (clobber (match_scratch:CC 3 "=X,&x,&x"))
9404 (clobber (match_scratch:SI 4 "=X,X,r"))]
9405 ""
9406 "*
9407{
9408 if (which_alternative != 0)
9409 return \"#\";
9410 else if (get_attr_length (insn) == 8)
9411 return \"{bdn|bdnz} %l0\";
9412 else
c81bebd7 9413 return \"bdz %$+8\;b %l0\";
5f81043f
RK
9414}"
9415 [(set_attr "type" "branch")
9416 (set_attr "length" "*,12,16")])
9417
1fd4e8c1
RK
9418(define_split
9419 [(set (pc)
9420 (if_then_else (match_operator 2 "comparison_operator"
cd2b37d9 9421 [(match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1
RK
9422 (const_int 1)])
9423 (match_operand 5 "" "")
9424 (match_operand 6 "" "")))
cd2b37d9 9425 (set (match_operand:SI 0 "gpc_reg_operand" "")
5f81043f
RK
9426 (plus:SI (match_dup 1)
9427 (const_int -1)))
1fd4e8c1
RK
9428 (clobber (match_scratch:CC 3 ""))
9429 (clobber (match_scratch:SI 4 ""))]
9430 "reload_completed"
9431 [(parallel [(set (match_dup 3)
5f81043f
RK
9432 (compare:CC (plus:SI (match_dup 1)
9433 (const_int -1))
1fd4e8c1 9434 (const_int 0)))
5f81043f
RK
9435 (set (match_dup 0)
9436 (plus:SI (match_dup 1)
9437 (const_int -1)))])
9438 (set (pc) (if_then_else (match_dup 7)
9439 (match_dup 5)
9440 (match_dup 6)))]
1fd4e8c1
RK
9441 "
9442{ operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3],
9443 const0_rtx); }")
9444
9445(define_split
9446 [(set (pc)
9447 (if_then_else (match_operator 2 "comparison_operator"
cd2b37d9 9448 [(match_operand:SI 1 "gpc_reg_operand" "")
1fd4e8c1
RK
9449 (const_int 1)])
9450 (match_operand 5 "" "")
9451 (match_operand 6 "" "")))
9452 (set (match_operand:SI 0 "general_operand" "")
9453 (plus:SI (match_dup 1) (const_int -1)))
9454 (clobber (match_scratch:CC 3 ""))
9455 (clobber (match_scratch:SI 4 ""))]
cd2b37d9 9456 "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
1fd4e8c1 9457 [(parallel [(set (match_dup 3)
5f81043f
RK
9458 (compare:CC (plus:SI (match_dup 1)
9459 (const_int -1))
1fd4e8c1 9460 (const_int 0)))
5f81043f
RK
9461 (set (match_dup 4)
9462 (plus:SI (match_dup 1)
9463 (const_int -1)))])
9464 (set (match_dup 0)
9465 (match_dup 4))
9466 (set (pc) (if_then_else (match_dup 7)
9467 (match_dup 5)
9468 (match_dup 6)))]
1fd4e8c1
RK
9469 "
9470{ operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3],
9471 const0_rtx); }")
This page took 1.644443 seconds and 5 git commands to generate.