]> gcc.gnu.org Git - gcc.git/blame - gcc/config/ia64/ia64.md
Fix typo found by bootstrap.
[gcc.git] / gcc / config / ia64 / ia64.md
CommitLineData
c65ebc55 1;; IA-64 Machine description template
e65271be 2;; Copyright (C) 1999, 2000 Free Software Foundation, Inc.
c65ebc55
JW
3;; Contributed by James E. Wilson <wilson@cygnus.com> and
4;; David Mosberger <davidm@hpl.hp.com>.
5
6;; This file is part of GNU CC.
7
8;; GNU CC is free software; you can redistribute it and/or modify
9;; it under the terms of the GNU General Public License as published by
10;; the Free Software Foundation; either version 2, or (at your option)
11;; any later version.
12
13;; GNU CC is distributed in the hope that it will be useful,
14;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16;; GNU General Public License for more details.
17
18;; You should have received a copy of the GNU General Public License
19;; along with GNU CC; see the file COPYING. If not, write to
20;; the Free Software Foundation, 59 Temple Place - Suite 330,
21;; Boston, MA 02111-1307, USA.
22
23;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24
25;; ??? Add support for long double XFmode patterns.
26
27;; ??? register_operand accepts (subreg:DI (mem:SI X)) which forces later
28;; reload. This will be fixed once scheduling support is turned on.
29
30;; ??? Optimize for post-increment addressing modes.
31
32;; ??? fselect is not supported, because there is no integer register
33;; equivalent.
34
35;; ??? fp abs/min/max instructions may also work for integer values.
36
37;; ??? Would a predicate_reg_operand predicate be useful? The HP one is buggy,
38;; it assumes the operand is a register and takes REGNO of it without checking.
39
40;; ??? Would a branch_reg_operand predicate be useful? The HP one is buggy,
41;; it assumes the operand is a register and takes REGNO of it without checking.
42
43;; ??? Go through list of documented named patterns and look for more to
44;; implement.
45
46;; ??? Go through instruction manual and look for more instructions that
47;; can be emitted.
48
49;; ??? Add function unit scheduling info for Itanium (TM) processor.
50
ce152ef8
AM
51;; ??? The explicit stop in the flushrs pattern is not ideal. It
52;; would be better if rtx_needs_barrier took care of this, but this is
53;; something that can be fixed later.
54
e5bde68a
RH
55;; Unspec usage:
56;;
57;; unspec:
58;; 1 gr_spill
59;; 2 gr_restore
60;; 3 fr_spill
61;; 4 fr_restore
62;; 5 pr_spill
63;; 8 popcnt
64;; 9 unat_spill
65;; 10 unat_restore
66;; 13 cmpxchg_acq
67;; 14 val_compare_and_swap
68;; 16 lock_test_and_set
69;; 17 op_and_fetch
70;; 18 fetch_and_op
71;; 19 fetchadd_acq
72;; 20 bsp_value
ce152ef8 73;; 21 flushrs
e5bde68a
RH
74;;
75;; unspec_volatile:
76;; 0 alloc
77;; 1 blockage
78;; 2 insn_group_barrier
79;; 3 flush_cache
80;; 4 pfs_restore
81;; 5 set_bsp
82;; 6 pr_restore
c65ebc55
JW
83\f
84;; ::::::::::::::::::::
85;; ::
86;; :: Attributes
87;; ::
88;; ::::::::::::::::::::
89
90;; Instruction type. This primarily determines how instructions can be
91;; packed in bundles, and secondarily affects scheduling to function units.
92
93;; A alu, can go in I or M syllable of a bundle
94;; I integer
95;; M memory
96;; F floating-point
97;; B branch
98;; L long immediate, takes two syllables
99;; S stop bit
100
101;; ??? Should not have any pattern with type unknown. Perhaps add code to
102;; check this in md_reorg? Currently use unknown for patterns which emit
103;; multiple instructions, patterns which emit 0 instructions, and patterns
104;; which emit instruction that can go in any slot (e.g. nop).
105
106(define_attr "type" "unknown,A,I,M,F,B,L,S" (const_string "unknown"))
107
e5bde68a
RH
108;; Predication. True iff this instruction can be predicated.
109
110(define_attr "predicable" "no,yes" (const_string "yes"))
111
c65ebc55
JW
112\f
113;; ::::::::::::::::::::
114;; ::
115;; :: Function Units
116;; ::
117;; ::::::::::::::::::::
118
119;; Each usage of a function units by a class of insns is specified with a
120;; `define_function_unit' expression, which looks like this:
121;; (define_function_unit NAME MULTIPLICITY SIMULTANEITY TEST READY-DELAY
122;; ISSUE-DELAY [CONFLICT-LIST])
123
124;; This default scheduling info seeks to pack instructions into bundles
125;; efficiently to reduce code size, so we just list how many of each
126;; instruction type can go in a bundle. ISSUE_RATE is set to 3.
127
128;; ??? Add scheduler ready-list hook (MD_SCHED_REORDER) that orders
129;; instructions, so that the next instruction can fill the next bundle slot.
130;; This really needs to know where the stop bits are though.
131
132;; ??? Use MD_SCHED_REORDER to put alloc first instead of using an unspec
133;; volatile. Use ADJUST_PRIORITY to set the priority of alloc very high to
134;; make it schedule first.
135
136;; ??? Modify the md_reorg code that emits stop bits so that instead of putting
137;; them in the last possible place, we put them in places where bundles allow
138;; them. This should reduce code size, but may decrease performance if we end
139;; up with more stop bits than the minimum we need.
140
141;; Alu instructions can execute on either the integer or memory function
142;; unit. We indicate this by defining an alu function unit, and then marking
143;; it as busy everytime we issue a integer or memory type instruction.
144
145(define_function_unit "alu" 3 1 (eq_attr "type" "A,I,M") 1 0)
146
147(define_function_unit "integer" 2 1 (eq_attr "type" "I") 1 0)
148
149(define_function_unit "memory" 3 1 (eq_attr "type" "M") 1 0)
150
151(define_function_unit "floating_point" 1 1 (eq_attr "type" "F") 1 0)
152
153(define_function_unit "branch" 3 1 (eq_attr "type" "B") 1 0)
154
155;; ??? This isn't quite right, because we can only fit two insns in a bundle
156;; when using an L type instruction. That isn't modeled currently.
157
158(define_function_unit "long_immediate" 1 1 (eq_attr "type" "L") 1 0)
159
160\f
161;; ::::::::::::::::::::
162;; ::
163;; :: Moves
164;; ::
165;; ::::::::::::::::::::
166
167(define_expand "movqi"
168 [(set (match_operand:QI 0 "general_operand" "")
169 (match_operand:QI 1 "general_operand" ""))]
170 ""
171 "
172{
173 if (! reload_in_progress && ! reload_completed
174 && GET_CODE (operands[0]) == MEM
175 && GET_CODE (operands[1]) == MEM)
176 operands[1] = copy_to_mode_reg (QImode, operands[1]);
177}")
178
179(define_insn "*movqi_internal"
180 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,m,r,*e")
181 (match_operand:QI 1 "move_operand" "r,J,m,r,*e,r"))]
182 "! memory_operand (operands[0], QImode)
183 || ! memory_operand (operands[1], QImode)"
184 "@
185 mov %0 = %1
186 addl %0 = %1, r0
187 ld1%O1 %0 = %1%P1
188 st1%Q0 %0 = %1%P0
189 getf.sig %0 = %1
190 setf.sig %0 = %1"
191 [(set_attr "type" "A,A,M,M,M,M")])
192
193(define_expand "movhi"
194 [(set (match_operand:HI 0 "general_operand" "")
195 (match_operand:HI 1 "general_operand" ""))]
196 ""
197 "
198{
199 if (! reload_in_progress && ! reload_completed
200 && GET_CODE (operands[0]) == MEM
201 && GET_CODE (operands[1]) == MEM)
202 operands[1] = copy_to_mode_reg (HImode, operands[1]);
203}")
204
205(define_insn "*movhi_internal"
206 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r,*e")
207 (match_operand:HI 1 "move_operand" "r,J,m,r,*e,r"))]
208 "! memory_operand (operands[0], HImode)
209 || !memory_operand (operands[1], HImode)"
210 "@
211 mov %0 = %1
212 addl %0 = %1, r0
213 ld2%O1 %0 = %1%P1
214 st2%Q0 %0 = %1%P0
215 getf.sig %0 = %1
216 setf.sig %0 = %1"
217 [(set_attr "type" "A,A,M,M,M,M")])
218
219(define_expand "movsi"
220 [(set (match_operand:SI 0 "general_operand" "")
221 (match_operand:SI 1 "general_operand" ""))]
222 ""
223 "
224{
225 if (! reload_in_progress && ! reload_completed
226 && GET_CODE (operands[0]) == MEM
227 && GET_CODE (operands[1]) == MEM)
228 operands[1] = copy_to_mode_reg (SImode, operands[1]);
229}")
230
231(define_insn "*movsi_internal"
232 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,r,*e,*e,r,*f")
233 (match_operand:SI 1 "move_operand" "r,J,i,m,r,*e,r,*e,*f,r"))]
234 "! memory_operand (operands[0], SImode)
235 || ! memory_operand (operands[1], SImode)"
236 "@
237 mov %0 = %1
238 addl %0 = %1, r0
239 movl %0 = %1
240 ld4%O1 %0 = %1%P1
241 st4%Q0 %0 = %1%P0
242 getf.sig %0 = %1
243 setf.sig %0 = %1
244 mov %0 = %1
245 getf.s %0 = %1
246 setf.s %0 = %1"
247 [(set_attr "type" "A,A,L,M,M,M,M,F,M,M")])
248
249(define_expand "movdi"
250 [(set (match_operand:DI 0 "general_operand" "")
251 (match_operand:DI 1 "general_operand" ""))]
252 ""
253 "
254{
255 /* ??? Should generalize this, so that we can also support 32 bit
256 pointers. */
257 if (! TARGET_NO_PIC && symbolic_operand (operands[1], DImode))
258 {
259 rtx temp;
260
261 /* Operand[0] could be a MEM, which isn't a valid destination for the
262 PIC load address patterns. */
263 if (! register_operand (operands[0], DImode))
264 temp = gen_reg_rtx (DImode);
265 else
266 temp = operands[0];
267
59da9a7d
JW
268 if (TARGET_AUTO_PIC)
269 emit_insn (gen_load_gprel64 (temp, operands[1]));
270 else if (GET_CODE (operands[1]) == SYMBOL_REF
271 && SYMBOL_REF_FLAG (operands[1]))
c65ebc55
JW
272 emit_insn (gen_load_fptr (temp, operands[1]));
273 else if (sdata_symbolic_operand (operands[1], DImode))
274 emit_insn (gen_load_gprel (temp, operands[1]));
275 else
276 emit_insn (gen_load_symptr (temp, operands[1]));
277
278 if (temp == operands[0])
279 DONE;
280
281 operands[1] = temp;
282 }
283
284 if (! reload_in_progress && ! reload_completed
285 && GET_CODE (operands[0]) == MEM
286 && GET_CODE (operands[1]) == MEM)
287 operands[1] = copy_to_mode_reg (DImode, operands[1]);
288}")
289
290;; ??? Emit stf8 for m/*e constraint.
291(define_insn "*movdi_internal"
292 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,r,*e,*e,r,*f,r,*b")
293 (match_operand:DI 1 "move_operand" "r,J,i,m,r,*e,r,*e,*f,r,*b,r"))]
294 "! memory_operand (operands[0], DImode)
295 || ! memory_operand (operands[1], DImode)"
296 "@
297 mov %0 = %1
298 addl %0 = %1, r0
299 movl %0 = %1
300 ld8%O1 %0 = %1%P1
301 st8%Q0 %0 = %1%P0
302 getf.sig %0 = %1
303 setf.sig %0 = %1
304 mov %0 = %1
305 getf.d %0 = %1
306 setf.d %0 = %1
307 mov %0 = %1
308 mov %0 = %1"
309 [(set_attr "type" "A,A,L,M,M,M,M,F,M,M,I,I")])
310
311(define_expand "load_fptr"
312 [(set (match_dup 2)
313 (plus:DI (reg:DI 1) (match_operand:DI 1 "function_operand" "")))
314 (set (match_operand:DI 0 "register_operand" "") (mem:DI (match_dup 2)))]
315 ""
316 "
317{
318 if (reload_in_progress)
319 operands[2] = operands[0];
320 else
321 operands[2] = gen_reg_rtx (DImode);
322}")
323
324(define_insn "*load_fptr_internal1"
325 [(set (match_operand:DI 0 "register_operand" "=r")
326 (plus:DI (reg:DI 1) (match_operand:DI 1 "function_operand" "s")))]
327 ""
328 "addl %0 = @ltoff(@fptr(%1)), gp"
329 [(set_attr "type" "A")])
330
331(define_insn "load_gprel"
332 [(set (match_operand:DI 0 "register_operand" "=r")
333 (plus:DI (reg:DI 1) (match_operand:DI 1 "sdata_symbolic_operand" "s")))]
334 ""
335 "addl %0 = @gprel(%1), gp"
336 [(set_attr "type" "A")])
337
59da9a7d
JW
338(define_insn "gprel64_offset"
339 [(set (match_operand:DI 0 "register_operand" "=r")
340 (minus:DI (match_operand:DI 1 "symbolic_operand" "") (reg:DI 1)))]
341 ""
342 "movl %0 = @gprel(%1)"
343 [(set_attr "type" "L")])
344
345(define_expand "load_gprel64"
346 [(set (match_dup 2)
347 (minus:DI (match_operand:DI 1 "symbolic_operand" "") (reg:DI 1)))
348 (set (match_operand:DI 0 "register_operand" "")
349 (plus:DI (reg:DI 1) (match_dup 2)))]
350 ""
351 "{
352 if (reload_in_progress)
353 operands[2] = operands[0];
354 else
355 operands[2] = gen_reg_rtx (DImode);
356}")
357
c65ebc55
JW
358(define_expand "load_symptr"
359 [(set (match_dup 2)
360 (plus:DI (reg:DI 1) (match_operand:DI 1 "symbolic_operand" "")))
361 (set (match_operand:DI 0 "register_operand" "") (mem:DI (match_dup 2)))]
362 ""
363 "
364{
365 if (reload_in_progress)
366 operands[2] = operands[0];
367 else
368 operands[2] = gen_reg_rtx (DImode);
369}")
370
371(define_insn "*load_symptr_internal1"
372 [(set (match_operand:DI 0 "register_operand" "=r")
373 (plus:DI (reg:DI 1) (match_operand:DI 1 "symbolic_operand" "s")))]
374 ""
375 "addl %0 = @ltoff(%1), gp"
376 [(set_attr "type" "A")])
377
378;; Floating Point Moves
379;;
380;; Note - Patterns for SF mode moves are compulsory, but
381;; patterns for DF are optional, as GCC can synthesise them.
382
383(define_expand "movsf"
384 [(set (match_operand:SF 0 "general_operand" "")
385 (match_operand:SF 1 "general_operand" ""))]
386 ""
387 "
388{
389 if (! reload_in_progress && ! reload_completed
390 && GET_CODE (operands[0]) == MEM
391 && GET_CODE (operands[1]) == MEM)
392 operands[1] = copy_to_mode_reg (SFmode, operands[1]);
393}")
394
395;; ??? The r/m alternative is apparently needed because of paradoxical subregs,
396;; so it may no longer be necessary after scheduling is enabled.
397
398(define_insn "*movsf_internal"
399 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,m,*r,f,*r,*r")
400 (match_operand:SF 1 "general_operand" "fG,m,fG,fG,*r,*r,m"))]
401 "! memory_operand (operands[0], SFmode)
402 || ! memory_operand (operands[1], SFmode)"
403 "@
404 mov %0 = %F1
405 ldfs %0 = %1%P1
406 stfs %0 = %F1%P0
407 getf.s %0 = %F1
408 setf.s %0 = %1
409 mov %0 = %1
410 ld4%O1 %0 = %1"
411 [(set_attr "type" "F,M,M,M,M,A,M")])
412
413(define_expand "movdf"
414 [(set (match_operand:DF 0 "general_operand" "")
415 (match_operand:DF 1 "general_operand" ""))]
416 ""
417 "
418{
419 if (! reload_in_progress && ! reload_completed
420 && GET_CODE (operands[0]) == MEM
421 && GET_CODE (operands[1]) == MEM)
422 operands[1] = copy_to_mode_reg (DFmode, operands[1]);
423}")
424
425;; ??? movsf has a r/m alternative, movdf doesn't.
426
427(define_insn "*movdf_internal"
428 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,m,*r,f,*r")
429 (match_operand:DF 1 "general_operand" "fG,m,fG,fG,*r,*r"))]
430 "! memory_operand (operands[0], DFmode)
431 || ! memory_operand (operands[1], DFmode)"
432 "@
433 mov %0 = %F1
434 ldfd %0 = %1%P1
435 stfd %0 = %F1%P0
436 getf.d %0 = %F1
437 setf.d %0 = %1
438 mov %0 = %1"
439 [(set_attr "type" "F,M,M,M,M,A")])
440
e5bde68a
RH
441(define_expand "movxf"
442 [(set (match_operand:XF 0 "general_operand" "")
443 (match_operand:XF 1 "general_operand" ""))]
444 ""
445 "
446{
447 if (! reload_in_progress && ! reload_completed
448 && GET_CODE (operands[0]) == MEM
449 && GET_CODE (operands[1]) == MEM)
450 operands[1] = copy_to_mode_reg (XFmode, operands[1]);
451}")
452
453(define_insn "*movxf_internal"
454 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,f,m")
455 (match_operand:XF 1 "general_operand" "fG,m,fG"))]
456 "! memory_operand (operands[0], XFmode)
457 || ! memory_operand (operands[1], XFmode)"
458 "@
459 mov %0 = %F1
46b1ac3f
JW
460 ldfe %0 = %1%P1
461 stfe %0 = %F1%P0"
e5bde68a
RH
462 [(set_attr "type" "F,M,M")])
463
c65ebc55
JW
464\f
465;; ::::::::::::::::::::
466;; ::
467;; :: Conversions
468;; ::
469;; ::::::::::::::::::::
470
471;; Signed conversions from a smaller integer to a larger integer
472
473(define_insn "extendqidi2"
474 [(set (match_operand:DI 0 "register_operand" "=r")
475 (sign_extend:DI (match_operand:QI 1 "register_operand" "r")))]
476 ""
477 "sxt1 %0 = %1"
478 [(set_attr "type" "I")])
479
480(define_insn "extendhidi2"
481 [(set (match_operand:DI 0 "register_operand" "=r")
482 (sign_extend:DI (match_operand:HI 1 "register_operand" "r")))]
483 ""
484 "sxt2 %0 = %1"
485 [(set_attr "type" "I")])
486
487(define_insn "extendsidi2"
488 [(set (match_operand:DI 0 "register_operand" "=r,*e")
489 (sign_extend:DI (match_operand:SI 1 "register_operand" "r,*e")))]
490 ""
491 "@
492 sxt4 %0 = %1
493 fsxt.r %0 = %1, %1%B0"
494 [(set_attr "type" "I,F")])
495
496;; Unsigned conversions from a smaller integer to a larger integer
497
498(define_insn "zero_extendqidi2"
499 [(set (match_operand:DI 0 "register_operand" "=r,r")
500 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
501 ""
502 "@
503 zxt1 %0 = %1
504 ld1%O1 %0 = %1%P1"
505 [(set_attr "type" "I,M")])
506
507(define_insn "zero_extendhidi2"
508 [(set (match_operand:DI 0 "register_operand" "=r,r")
509 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
510 ""
511 "@
512 zxt2 %0 = %1
513 ld2%O1 %0 = %1%P1"
514 [(set_attr "type" "I,M")])
515
516(define_insn "zero_extendsidi2"
517 [(set (match_operand:DI 0 "register_operand" "=r,r,*e")
518 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,*e")))]
519 ""
520 "@
521 zxt4 %0 = %1
522 ld4%O1 %0 = %1%P1
523 fsxt.r %0 = f1, %1%B0"
524 [(set_attr "type" "I,M,F")])
525
526;; Convert between floating point types of different sizes.
527
e8e20f18
RH
528;; ??? Optimization opportunity here. Get rid of the insn altogether
529;; when we can. Should probably use a scheme like has been proposed
530;; for ia32 in dealing with operands that match unary operators. This
531;; would let combine merge the thing into adjacent insns.
c65ebc55 532
e8e20f18 533(define_insn_and_split "extendsfdf2"
c65ebc55
JW
534 [(set (match_operand:DF 0 "register_operand" "=f,f")
535 (float_extend:DF (match_operand:SF 1 "register_operand" "0,f")))]
536 ""
e8e20f18 537 "mov %0 = %1"
50798048 538 "reload_completed"
e8e20f18
RH
539 [(set (match_dup 0) (float_extend:DF (match_dup 1)))]
540 "if (true_regnum (operands[0]) == true_regnum (operands[1])) DONE;"
541 [(set_attr "type" "F")])
c65ebc55
JW
542
543(define_insn "truncdfsf2"
544 [(set (match_operand:SF 0 "register_operand" "=f")
545 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
546 ""
547 "fnorm.s %0 = %1%B0"
548 [(set_attr "type" "F")])
549
e5bde68a
RH
550(define_insn "truncxfsf2"
551 [(set (match_operand:SF 0 "register_operand" "=f")
552 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
553 ""
554 "fnorm.s %0 = %1%B0"
555 [(set_attr "type" "F")])
c65ebc55 556
e5bde68a 557(define_insn "truncxfdf2"
c65ebc55 558 [(set (match_operand:DF 0 "register_operand" "=f")
e5bde68a 559 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
c65ebc55 560 ""
e5bde68a
RH
561 "fnorm.d %0 = %1%B0"
562 [(set_attr "type" "F")])
563
564;; Convert between signed integer types and floating point.
565
566(define_insn "floatdixf2"
567 [(set (match_operand:XF 0 "register_operand" "=f")
568 (float:XF (match_operand:DI 1 "register_operand" "e")))]
569 ""
570 "fcvt.xf %0 = %1"
571 [(set_attr "type" "F")])
c65ebc55
JW
572
573(define_insn "fix_truncsfdi2"
574 [(set (match_operand:DI 0 "register_operand" "=e")
575 (fix:DI (match_operand:SF 1 "register_operand" "f")))]
576 ""
577 "fcvt.fx.trunc %0 = %1%B0"
578 [(set_attr "type" "F")])
579
580(define_insn "fix_truncdfdi2"
581 [(set (match_operand:DI 0 "register_operand" "=e")
582 (fix:DI (match_operand:DF 1 "register_operand" "f")))]
583 ""
584 "fcvt.fx.trunc %0 = %1%B0"
585 [(set_attr "type" "F")])
586
587;; Convert between unsigned integer types and floating point.
588
589(define_insn "floatunsdisf2"
590 [(set (match_operand:SF 0 "register_operand" "=f")
591 (unsigned_float:SF (match_operand:DI 1 "register_operand" "e")))]
592 ""
593 "fcvt.xuf.s %0 = %1%B0"
594 [(set_attr "type" "F")])
595
596(define_insn "floatunsdidf2"
597 [(set (match_operand:DF 0 "register_operand" "=f")
598 (unsigned_float:DF (match_operand:DI 1 "register_operand" "e")))]
599 ""
600 "fcvt.xuf.d %0 = %1%B0"
601 [(set_attr "type" "F")])
602
603(define_insn "fixuns_truncsfdi2"
604 [(set (match_operand:DI 0 "register_operand" "=e")
605 (unsigned_fix:DI (match_operand:SF 1 "register_operand" "f")))]
606 ""
607 "fcvt.fxu.trunc %0 = %1%B0"
608 [(set_attr "type" "F")])
609
610(define_insn "fixuns_truncdfdi2"
611 [(set (match_operand:DI 0 "register_operand" "=e")
612 (unsigned_fix:DI (match_operand:DF 1 "register_operand" "f")))]
613 ""
614 "fcvt.fxu.trunc %0 = %1%B0"
615 [(set_attr "type" "F")])
616
617\f
618;; ::::::::::::::::::::
619;; ::
620;; :: Bit field extraction
621;; ::
622;; ::::::::::::::::::::
623
624;; ??? It would be useful to have SImode versions of the extract and insert
625;; patterns.
626
627(define_insn "extv"
628 [(set (match_operand:DI 0 "register_operand" "=r")
629 (sign_extract:DI (match_operand:DI 1 "register_operand" "r")
630 (match_operand:DI 2 "const_int_operand" "n")
631 (match_operand:DI 3 "const_int_operand" "n")))]
632 ""
633 "extr %0 = %1, %3, %2"
634 [(set_attr "type" "I")])
635
636(define_insn "extzv"
637 [(set (match_operand:DI 0 "register_operand" "=r")
638 (zero_extract:DI (match_operand:DI 1 "register_operand" "r")
639 (match_operand:DI 2 "const_int_operand" "n")
640 (match_operand:DI 3 "const_int_operand" "n")))]
641 ""
642 "extr.u %0 = %1, %3, %2"
643 [(set_attr "type" "I")])
644
645;; Insert a bit field.
646;; Can have 3 operands, source1 (inserter), source2 (insertee), dest.
647;; Source1 can be 0 or -1.
648;; Source2 can be 0.
649
650;; ??? Actual dep instruction is more powerful than what these insv
651;; patterns support. Unfortunately, combine is unable to create patterns
652;; where source2 != dest.
653
654(define_expand "insv"
655 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
656 (match_operand:DI 1 "const_int_operand" "")
657 (match_operand:DI 2 "const_int_operand" ""))
658 (match_operand:DI 3 "nonmemory_operand" ""))]
659 ""
660 "
661{
662 int width = INTVAL (operands[1]);
663 int shift = INTVAL (operands[2]);
664
665 /* If operand[3] is a constant, and isn't 0 or -1, then load it into a
666 pseudo. */
667 if (! register_operand (operands[3], DImode)
668 && operands[3] != const0_rtx && operands[3] != constm1_rtx)
669 operands[3] = force_reg (DImode, operands[3]);
670
671 /* If this is a single dep instruction, we have nothing to do. */
672 if (! ((register_operand (operands[3], DImode) && width <= 16)
673 || operands[3] == const0_rtx || operands[3] == constm1_rtx))
674 {
675 /* Check for cases that can be implemented with a mix instruction. */
676 if (width == 32 && shift == 0)
677 {
678 /* Directly generating the mix4left instruction confuses
679 optimize_bit_field in function.c. Since this is performing
680 a useful optimization, we defer generation of the complicated
681 mix4left RTL to the first splitting phase. */
682 rtx tmp = gen_reg_rtx (DImode);
683 emit_insn (gen_shift_mix4left (operands[0], operands[3], tmp));
684 DONE;
685 }
686 else if (width == 32 && shift == 32)
687 {
688 emit_insn (gen_mix4right (operands[0], operands[3]));
689 DONE;
690 }
691
d2ba6dcf
JW
692 /* We could handle remaining cases by emitting multiple dep
693 instructions.
694
695 If we need more than two dep instructions then we lose. A 6
696 insn sequence mov mask1,mov mask2,shl;;and,and;;or is better than
697 mov;;dep,shr;;dep,shr;;dep. The former can be executed in 3 cycles,
698 the latter is 6 cycles on an Itanium (TM) processor, because there is
699 only one function unit that can execute dep and shr immed.
700
701 If we only need two dep instruction, then we still lose.
702 mov;;dep,shr;;dep is still 4 cycles. Even if we optimize away
703 the unnecessary mov, this is still undesirable because it will be
704 hard to optimize, and it creates unnecessary pressure on the I0
705 function unit. */
706
c65ebc55
JW
707 FAIL;
708
709#if 0
710 /* This code may be useful for other IA-64 processors, so we leave it in
711 for now. */
712 while (width > 16)
713 {
714 rtx tmp;
715
716 emit_insn (gen_insv (operands[0], GEN_INT (16), GEN_INT (shift),
717 operands[3]));
718 shift += 16;
719 width -= 16;
720 tmp = gen_reg_rtx (DImode);
721 emit_insn (gen_lshrdi3 (tmp, operands[3], GEN_INT (16)));
722 operands[3] = tmp;
723 }
724 operands[1] = GEN_INT (width);
725 operands[2] = GEN_INT (shift);
726#endif
727 }
728}")
729
730(define_insn "*insv_internal"
731 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
732 (match_operand:DI 1 "const_int_operand" "n")
733 (match_operand:DI 2 "const_int_operand" "n"))
734 (match_operand:DI 3 "nonmemory_operand" "rP"))]
735 "(register_operand (operands[3], DImode) && INTVAL (operands[1]) <= 16)
736 || operands[3] == const0_rtx || operands[3] == constm1_rtx"
737 "dep %0 = %3, %0, %2, %1"
738 [(set_attr "type" "I")])
739
740(define_insn "shift_mix4left"
741 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
742 (const_int 32) (const_int 0))
743 (match_operand:DI 1 "register_operand" "r"))
744 (clobber (match_operand:DI 2 "register_operand" "=r"))]
745 ""
746 "#"
747 [(set_attr "type" "unknown")])
748
749;; ??? Need to emit an instruction group barrier here because this gets split
750;; after md_reorg.
751
752(define_split
753 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
754 (const_int 32) (const_int 0))
755 (match_operand:DI 1 "register_operand" ""))
756 (clobber (match_operand:DI 2 "register_operand" ""))]
757 "reload_completed"
758 [(set (match_dup 3) (ashift:DI (match_dup 1) (const_int 32)))
759 (unspec_volatile [(const_int 0)] 2)
760 (set (zero_extract:DI (match_dup 0) (const_int 32) (const_int 0))
761 (lshiftrt:DI (match_dup 3) (const_int 32)))]
762 "operands[3] = operands[2];")
763
764(define_split
765 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
766 (const_int 32) (const_int 0))
767 (match_operand:DI 1 "register_operand" ""))
768 (clobber (match_operand:DI 2 "register_operand" ""))]
769 "! reload_completed"
770 [(set (match_dup 3) (ashift:DI (match_dup 1) (const_int 32)))
771 (set (zero_extract:DI (match_dup 0) (const_int 32) (const_int 0))
772 (lshiftrt:DI (match_dup 3) (const_int 32)))]
773 "operands[3] = operands[2];")
774
775(define_insn "*mix4left"
776 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
777 (const_int 32) (const_int 0))
778 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
779 (const_int 32)))]
780 ""
781 "mix4.l %0 = %0, %r1"
782 [(set_attr "type" "I")])
783
784(define_insn "mix4right"
785 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
786 (const_int 32) (const_int 32))
787 (match_operand:DI 1 "reg_or_0_operand" "rO"))]
788 ""
789 "mix4.r %0 = %r1, %0"
790 [(set_attr "type" "I")])
791
792;; This is used by the rotrsi3 pattern.
793
794(define_insn "*mix4right_3op"
795 [(set (match_operand:DI 0 "register_operand" "=r")
796 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
797 (ashift:DI (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))
798 (const_int 32))))]
799 ""
fa9a44e8 800 "mix4.r %0 = %2, %1"
c65ebc55
JW
801 [(set_attr "type" "I")])
802
803\f
804;; ::::::::::::::::::::
805;; ::
806;; :: 32 bit Integer arithmetic
807;; ::
808;; ::::::::::::::::::::
809
810;; We handle 32-bit arithmetic just like the alpha port does.
811
812(define_expand "addsi3"
813 [(set (match_operand:SI 0 "register_operand" "")
814 (plus:SI (match_operand:SI 1 "register_operand" "")
815 (match_operand:SI 2 "reg_or_22bit_operand" "")))]
816 ""
817 "
818{
819 if (optimize)
820 {
821 rtx op1 = gen_lowpart (DImode, operands[1]);
822 rtx op2 = gen_lowpart (DImode, operands[2]);
823
824 if (! cse_not_expected)
825 {
826 rtx tmp = gen_reg_rtx (DImode);
827 emit_insn (gen_adddi3 (tmp, op1, op2));
828 emit_move_insn (operands[0], gen_lowpart (SImode, tmp));
829 }
830 else
831 emit_insn (gen_adddi3 (gen_lowpart (DImode, operands[0]), op1, op2));
832 DONE;
833 }
834}")
835
836(define_insn "*addsi3_internal"
837 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
838 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,a")
839 (match_operand:SI 2 "reg_or_22bit_operand" "r,I,J")))]
840 ""
841 "@
842 add %0 = %1, %2
843 adds %0 = %2, %1
844 addl %0 = %2, %1"
845 [(set_attr "type" "A")])
846
847(define_insn "*addsi3_plus1"
848 [(set (match_operand:SI 0 "register_operand" "=r")
849 (plus:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
850 (match_operand:SI 2 "register_operand" "r"))
851 (const_int 1)))]
852 ""
853 "add %0 = %1, %2, 1"
854 [(set_attr "type" "A")])
855
856(define_expand "subsi3"
857 [(set (match_operand:SI 0 "register_operand" "")
858 (minus:SI (match_operand:SI 1 "reg_or_8bit_operand" "")
859 (match_operand:SI 2 "register_operand" "")))]
860 ""
861 "
862{
863 if (optimize)
864 {
865 rtx op1 = gen_lowpart (DImode, operands[1]);
866 rtx op2 = gen_lowpart (DImode, operands[2]);
867
868 if (! cse_not_expected)
869 {
870 rtx tmp = gen_reg_rtx (DImode);
871 emit_insn (gen_subdi3 (tmp, op1, op2));
872 emit_move_insn (operands[0], gen_lowpart (SImode, tmp));
873 }
874 else
875 emit_insn (gen_subdi3 (gen_lowpart (DImode, operands[0]), op1, op2));
876 DONE;
877 }
878}")
879
880(define_insn "*subsi3_internal"
881 [(set (match_operand:SI 0 "register_operand" "=r")
882 (minus:SI (match_operand:SI 1 "reg_or_8bit_operand" "rK")
883 (match_operand:SI 2 "register_operand" "r")))]
884 ""
885 "sub %0 = %1, %2"
886 [(set_attr "type" "A")])
887
888(define_insn "*subsi3_minus1"
889 [(set (match_operand:SI 0 "register_operand" "=r")
890 (plus:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
891 (match_operand:SI 2 "register_operand" "r")))]
892 ""
893 "sub %0 = %2, %1, 1"
894 [(set_attr "type" "A")])
895
896(define_expand "mulsi3"
897 [(set (match_operand:SI 0 "register_operand" "")
898 (mult:SI (match_operand:SI 1 "register_operand" "")
899 (match_operand:SI 2 "register_operand" "")))]
900 ""
901 "
902{
903 if (optimize)
904 {
905 rtx op1 = gen_lowpart (DImode, operands[1]);
906 rtx op2 = gen_lowpart (DImode, operands[2]);
907
908 if (! cse_not_expected)
909 {
910 rtx tmp = gen_reg_rtx (DImode);
911 emit_insn (gen_muldi3 (tmp, op1, op2));
912 emit_move_insn (operands[0], gen_lowpart (SImode, tmp));
913 }
914 else
915 emit_insn (gen_muldi3 (gen_lowpart (DImode, operands[0]), op1, op2));
916 DONE;
917 }
918}")
919
920;; ??? Could add maddsi3 patterns patterned after the madddi3 patterns.
921
922(define_insn "*mulsi3_internal"
923 [(set (match_operand:SI 0 "register_operand" "=e")
924 (mult:SI (match_operand:SI 1 "register_operand" "e")
925 (match_operand:SI 2 "nonmemory_operand" "e")))]
926 ""
927 "xma.l %0 = %1, %2, f0%B0"
928 [(set_attr "type" "F")])
929
930(define_expand "negsi2"
931 [(set (match_operand:SI 0 "register_operand" "")
932 (neg:SI (match_operand:SI 1 "register_operand" "")))]
933 ""
934 "
935{
936 if (optimize)
937 {
938 rtx op1 = gen_lowpart (DImode, operands[1]);
939
940 if (! cse_not_expected)
941 {
942 rtx tmp = gen_reg_rtx (DImode);
943 emit_insn (gen_negdi2 (tmp, op1));
944 emit_move_insn (operands[0], gen_lowpart (SImode, tmp));
945 }
946 else
947 emit_insn (gen_negdi2 (gen_lowpart (DImode, operands[0]), op1));
948 DONE;
949 }
950}")
951
952(define_insn "*negsi2_internal"
953 [(set (match_operand:SI 0 "register_operand" "=r")
954 (neg:SI (match_operand:SI 1 "register_operand" "r")))]
955 ""
956 "sub %0 = r0, %1"
957 [(set_attr "type" "A")])
958
959(define_expand "abssi2"
960 [(set (match_dup 2)
961 (ge:CC (match_operand:SI 1 "register_operand" "") (const_int 0)))
962 (set (match_operand:SI 0 "register_operand" "")
e5bde68a
RH
963 (if_then_else:SI (eq:CC (match_dup 2) (const_int 0))
964 (neg:SI (match_dup 1))
965 (match_dup 1)))]
c65ebc55
JW
966 ""
967 "
968{
969 operands[2] = gen_reg_rtx (CCmode);
970}")
971
972(define_expand "sminsi3"
973 [(set (match_dup 3)
974 (ge:CC (match_operand:SI 1 "register_operand" "")
975 (match_operand:SI 2 "register_operand" "")))
976 (set (match_operand:SI 0 "register_operand" "")
977 (if_then_else:SI (ne:CC (match_dup 3) (const_int 0))
978 (match_dup 2) (match_dup 1)))]
979 ""
980 "
981{
982 operands[3] = gen_reg_rtx (CCmode);
983}")
984
985(define_expand "smaxsi3"
986 [(set (match_dup 3)
987 (ge:CC (match_operand:SI 1 "register_operand" "")
988 (match_operand:SI 2 "register_operand" "")))
989 (set (match_operand:SI 0 "register_operand" "")
990 (if_then_else:SI (ne:CC (match_dup 3) (const_int 0))
991 (match_dup 1) (match_dup 2)))]
992 ""
993 "
994{
995 operands[3] = gen_reg_rtx (CCmode);
996}")
997
998(define_expand "uminsi3"
999 [(set (match_dup 3)
1000 (geu:CC (match_operand:SI 1 "register_operand" "")
1001 (match_operand:SI 2 "register_operand" "")))
1002 (set (match_operand:SI 0 "register_operand" "")
1003 (if_then_else:SI (ne:CC (match_dup 3) (const_int 0))
1004 (match_dup 2) (match_dup 1)))]
1005 ""
1006 "
1007{
1008 operands[3] = gen_reg_rtx (CCmode);
1009}")
1010
1011(define_expand "umaxsi3"
1012 [(set (match_dup 3)
1013 (geu:CC (match_operand:SI 1 "register_operand" "")
1014 (match_operand:SI 2 "register_operand" "")))
1015 (set (match_operand:SI 0 "register_operand" "")
1016 (if_then_else:SI (ne:CC (match_dup 3) (const_int 0))
1017 (match_dup 1) (match_dup 2)))]
1018 ""
1019 "
1020{
1021 operands[3] = gen_reg_rtx (CCmode);
1022}")
1023
1024\f
1025;; ::::::::::::::::::::
1026;; ::
1027;; :: 64 bit Integer arithmetic
1028;; ::
1029;; ::::::::::::::::::::
1030
1031(define_insn "adddi3"
1032 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
1033 (plus:DI (match_operand:DI 1 "register_operand" "%r,r,a")
1034 (match_operand:DI 2 "reg_or_22bit_operand" "r,I,J")))]
1035 ""
1036 "@
1037 add %0 = %1, %2
1038 adds %0 = %2, %1
1039 addl %0 = %2, %1"
1040 [(set_attr "type" "A")])
1041
1042(define_insn "*adddi3_plus1"
1043 [(set (match_operand:DI 0 "register_operand" "=r")
1044 (plus:DI (plus:DI (match_operand:DI 1 "register_operand" "r")
1045 (match_operand:DI 2 "register_operand" "r"))
1046 (const_int 1)))]
1047 ""
1048 "add %0 = %1, %2, 1"
1049 [(set_attr "type" "A")])
1050
1051(define_insn "subdi3"
1052 [(set (match_operand:DI 0 "register_operand" "=r")
1053 (minus:DI (match_operand:DI 1 "reg_or_8bit_operand" "rK")
1054 (match_operand:DI 2 "register_operand" "r")))]
1055 ""
1056 "sub %0 = %1, %2"
1057 [(set_attr "type" "A")])
1058
1059(define_insn "*subdi3_minus1"
1060 [(set (match_operand:DI 0 "register_operand" "=r")
1061 (plus:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
1062 (match_operand:DI 2 "register_operand" "r")))]
1063 ""
1064 "sub %0 = %2, %1, 1"
1065 [(set_attr "type" "A")])
1066
1067(define_insn "muldi3"
1068 [(set (match_operand:DI 0 "register_operand" "=e")
1069 (mult:DI (match_operand:DI 1 "register_operand" "e")
1070 (match_operand:DI 2 "register_operand" "e")))]
1071 ""
1072 "xma.l %0 = %1, %2, f0%B0"
1073 [(set_attr "type" "F")])
1074
1075;; ??? If operand 3 is an eliminable reg, then register elimination causes the
1076;; same problem that we have with shladd below. Unfortunately, this case is
1077;; much harder to fix because the multiply puts the result in an FP register,
1078;; but the add needs inputs from a general register. We add a spurious clobber
1079;; here so that it will be present just in case register elimination gives us
1080;; the funny result.
1081
1082;; ??? Maybe validate_changes should try adding match_scratch clobbers?
1083
1084;; ??? Maybe we should change how adds are canonicalized.
1085
1086(define_insn "*madddi3"
1087 [(set (match_operand:DI 0 "register_operand" "=e")
1088 (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "e")
1089 (match_operand:DI 2 "register_operand" "e"))
1090 (match_operand:DI 3 "register_operand" "e")))
1091 (clobber (match_scratch:DI 4 "=X"))]
1092 ""
1093 "xma.l %0 = %1, %2, %3%B0"
1094 [(set_attr "type" "F")])
1095
1096;; This can be created by register elimination if operand3 of shladd is an
1097;; eliminable register or has reg_equiv_constant set.
1098
1099;; We have to use nonmemory_operand for operand 4, to ensure that the
1100;; validate_changes call inside eliminate_regs will always succeed. If it
1101;; doesn't succeed, then this remain a madddi3 pattern, and will be reloaded
1102;; incorrectly.
1103
1104(define_insn "*madddi3_elim"
1105 [(set (match_operand:DI 0 "register_operand" "=&r")
1106 (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "e")
1107 (match_operand:DI 2 "register_operand" "e"))
1108 (match_operand:DI 3 "register_operand" "e"))
1109 (match_operand:DI 4 "nonmemory_operand" "rI")))
1110 (clobber (match_scratch:DI 5 "=e"))]
1111 "reload_in_progress"
1112 "#"
1113 [(set_attr "type" "unknown")])
1114
1115;; ??? Need to emit an instruction group barrier here because this gets split
1116;; after md_reorg.
1117
1118(define_split
1119 [(set (match_operand:DI 0 "register_operand" "")
1120 (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
1121 (match_operand:DI 2 "register_operand" ""))
1122 (match_operand:DI 3 "register_operand" ""))
1123 (match_operand:DI 4 "reg_or_14bit_operand" "")))
1124 (clobber (match_scratch:DI 5 ""))]
1125 "reload_completed"
1126 [(parallel [(set (match_dup 5) (plus:DI (mult:DI (match_dup 1) (match_dup 2))
1127 (match_dup 3)))
1128 (clobber (match_dup 0))])
1129 (unspec_volatile [(const_int 0)] 2)
1130 (set (match_dup 0) (match_dup 5))
1131 (unspec_volatile [(const_int 0)] 2)
1132 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
1133 "")
1134
1135;; ??? There are highpart multiply and add instructions, but we have no way
1136;; to generate them.
1137
1138(define_insn "smuldi3_highpart"
1139 [(set (match_operand:DI 0 "register_operand" "=e")
1140 (truncate:DI
1141 (lshiftrt:TI
1142 (mult:TI (sign_extend:TI (match_operand:DI 1 "register_operand" "e"))
1143 (sign_extend:TI (match_operand:DI 2 "register_operand" "e")))
1144 (const_int 64))))]
1145 ""
1146 "xma.h %0 = %1, %2, f0%B0"
1147 [(set_attr "type" "F")])
1148
1149(define_insn "umuldi3_highpart"
1150 [(set (match_operand:DI 0 "register_operand" "=e")
1151 (truncate:DI
1152 (lshiftrt:TI
1153 (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand" "e"))
1154 (zero_extend:TI (match_operand:DI 2 "register_operand" "e")))
1155 (const_int 64))))]
1156 ""
1157 "xma.hu %0 = %1, %2, f0%B0"
1158 [(set_attr "type" "F")])
1159
1160(define_insn "negdi2"
1161 [(set (match_operand:DI 0 "register_operand" "=r")
1162 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
1163 ""
1164 "sub %0 = r0, %1"
1165 [(set_attr "type" "A")])
1166
1167(define_expand "absdi2"
1168 [(set (match_dup 2)
1169 (ge:CC (match_operand:DI 1 "register_operand" "") (const_int 0)))
1170 (set (match_operand:DI 0 "register_operand" "")
e5bde68a
RH
1171 (if_then_else:DI (eq:CC (match_dup 2) (const_int 0))
1172 (neg:DI (match_dup 1))
1173 (match_dup 1)))]
c65ebc55
JW
1174 ""
1175 "
1176{
1177 operands[2] = gen_reg_rtx (CCmode);
1178}")
1179
1180(define_expand "smindi3"
1181 [(set (match_dup 3)
1182 (ge:CC (match_operand:DI 1 "register_operand" "")
1183 (match_operand:DI 2 "register_operand" "")))
1184 (set (match_operand:DI 0 "register_operand" "")
1185 (if_then_else:DI (ne:CC (match_dup 3) (const_int 0))
1186 (match_dup 2) (match_dup 1)))]
1187 ""
1188 "
1189{
1190 operands[3] = gen_reg_rtx (CCmode);
1191}")
1192
1193(define_expand "smaxdi3"
1194 [(set (match_dup 3)
1195 (ge:CC (match_operand:DI 1 "register_operand" "")
1196 (match_operand:DI 2 "register_operand" "")))
1197 (set (match_operand:DI 0 "register_operand" "")
1198 (if_then_else:DI (ne:CC (match_dup 3) (const_int 0))
1199 (match_dup 1) (match_dup 2)))]
1200 ""
1201 "
1202{
1203 operands[3] = gen_reg_rtx (CCmode);
1204}")
1205
1206(define_expand "umindi3"
1207 [(set (match_dup 3)
1208 (geu:CC (match_operand:DI 1 "register_operand" "")
1209 (match_operand:DI 2 "register_operand" "")))
1210 (set (match_operand:DI 0 "register_operand" "")
1211 (if_then_else:DI (ne:CC (match_dup 3) (const_int 0))
1212 (match_dup 2) (match_dup 1)))]
1213 ""
1214 "
1215{
1216 operands[3] = gen_reg_rtx (CCmode);
1217}")
1218
1219(define_expand "umaxdi3"
1220 [(set (match_dup 3)
1221 (geu:CC (match_operand:DI 1 "register_operand" "")
1222 (match_operand:DI 2 "register_operand" "")))
1223 (set (match_operand:DI 0 "register_operand" "")
1224 (if_then_else:DI (ne:CC (match_dup 3) (const_int 0))
1225 (match_dup 1) (match_dup 2)))]
1226 ""
1227 "
1228{
1229 operands[3] = gen_reg_rtx (CCmode);
1230}")
1231
1232(define_expand "ffsdi2"
1233 [(set (match_dup 6)
1234 (eq:CC (match_operand:DI 1 "register_operand" "") (const_int 0)))
1235 (set (match_dup 2) (plus:DI (match_dup 1) (const_int -1)))
1236 (set (match_dup 5) (const_int 0))
1237 (set (match_dup 3) (xor:DI (match_dup 1) (match_dup 2)))
1238 (set (match_dup 4) (unspec:DI [(match_dup 3)] 8))
1239 (set (match_operand:DI 0 "register_operand" "")
1240 (if_then_else:DI (ne:CC (match_dup 6) (const_int 0))
1241 (match_dup 5) (match_dup 4)))]
1242 ""
1243 "
1244{
1245 operands[2] = gen_reg_rtx (DImode);
1246 operands[3] = gen_reg_rtx (DImode);
1247 operands[4] = gen_reg_rtx (DImode);
1248 operands[5] = gen_reg_rtx (DImode);
1249 operands[6] = gen_reg_rtx (CCmode);
1250}")
1251
1252(define_insn "*popcnt"
1253 [(set (match_operand:DI 0 "register_operand" "=r")
1254 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] 8))]
1255 ""
1256 "popcnt %0 = %1"
1257 [(set_attr "type" "I")])
1258
1259\f
1260;; ::::::::::::::::::::
1261;; ::
1262;; :: 32 bit floating point arithmetic
1263;; ::
1264;; ::::::::::::::::::::
1265
1266(define_insn "addsf3"
1267 [(set (match_operand:SF 0 "register_operand" "=f")
1268 (plus:SF (match_operand:SF 1 "register_operand" "%f")
1269 (match_operand:SF 2 "reg_or_fp01_operand" "fG")))]
1270 ""
1271 "fadd.s %0 = %1, %F2%B0"
1272 [(set_attr "type" "F")])
1273
1274(define_insn "subsf3"
1275 [(set (match_operand:SF 0 "register_operand" "=f")
1276 (minus:SF (match_operand:SF 1 "reg_or_fp01_operand" "fG")
1277 (match_operand:SF 2 "reg_or_fp01_operand" "fG")))]
1278 ""
1279 "fsub.s %0 = %F1, %F2%B0"
1280 [(set_attr "type" "F")])
1281
1282(define_insn "mulsf3"
1283 [(set (match_operand:SF 0 "register_operand" "=f")
1284 (mult:SF (match_operand:SF 1 "register_operand" "%f")
1285 (match_operand:SF 2 "register_operand" "f")))]
1286 ""
1287 "fmpy.s %0 = %1, %2%B0"
1288 [(set_attr "type" "F")])
1289
1290(define_insn "abssf2"
1291 [(set (match_operand:SF 0 "register_operand" "=f")
1292 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
1293 ""
1294 "fabs %0 = %1%B0"
1295 [(set_attr "type" "F")])
1296
1297(define_insn "negsf2"
1298 [(set (match_operand:SF 0 "register_operand" "=f")
1299 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
1300 ""
1301 "fneg %0 = %1%B0"
1302 [(set_attr "type" "F")])
1303
1304(define_insn "*nabssf2"
1305 [(set (match_operand:SF 0 "register_operand" "=f")
1306 (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))]
1307 ""
1308 "fnegabs %0 = %1%B0"
1309 [(set_attr "type" "F")])
1310
1311(define_insn "minsf3"
1312 [(set (match_operand:SF 0 "register_operand" "=f")
1313 (smin:SF (match_operand:SF 1 "register_operand" "f")
1314 (match_operand:SF 2 "reg_or_fp01_operand" "fG")))]
1315 ""
1316 "fmin %0 = %1, %F2%B0"
1317 [(set_attr "type" "F")])
1318
1319(define_insn "maxsf3"
1320 [(set (match_operand:SF 0 "register_operand" "=f")
1321 (smax:SF (match_operand:SF 1 "register_operand" "f")
1322 (match_operand:SF 2 "reg_or_fp01_operand" "fG")))]
1323 ""
1324 "fmax %0 = %1, %F2%B0"
1325 [(set_attr "type" "F")])
1326
1327(define_insn "*maddsf3"
1328 [(set (match_operand:SF 0 "register_operand" "=f")
1329 (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1330 (match_operand:SF 2 "register_operand" "f"))
1331 (match_operand:SF 3 "reg_or_fp01_operand" "fG")))]
1332 ""
1333 "fma.s %0 = %1, %2, %F3%B0"
1334 [(set_attr "type" "F")])
1335
1336(define_insn "*msubsf3"
1337 [(set (match_operand:SF 0 "register_operand" "=f")
1338 (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1339 (match_operand:SF 2 "register_operand" "f"))
1340 (match_operand:SF 3 "reg_or_fp01_operand" "fG")))]
1341 ""
1342 "fms.s %0 = %1, %2, %F3%B0"
1343 [(set_attr "type" "F")])
1344
1345(define_insn "*nmulsf3"
1346 [(set (match_operand:SF 0 "register_operand" "=f")
1347 (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1348 (match_operand:SF 2 "register_operand" "f"))))]
1349 ""
1350 "fnmpy.s %0 = %1, %2%B0"
1351 [(set_attr "type" "F")])
1352
1353;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
1354
1355(define_insn "*nmaddsf3"
1356 [(set (match_operand:SF 0 "register_operand" "=f")
1357 (plus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1358 (match_operand:SF 2 "register_operand" "f")))
1359 (match_operand:SF 3 "reg_or_fp01_operand" "fG")))]
1360 ""
1361 "fnma.s %0 = %1, %2, %F3%B0"
1362 [(set_attr "type" "F")])
1363
1364\f
1365;; ::::::::::::::::::::
1366;; ::
1367;; :: 64 bit floating point arithmetic
1368;; ::
1369;; ::::::::::::::::::::
1370
1371(define_insn "adddf3"
1372 [(set (match_operand:DF 0 "register_operand" "=f")
1373 (plus:DF (match_operand:DF 1 "register_operand" "%f")
1374 (match_operand:DF 2 "reg_or_fp01_operand" "fG")))]
1375 ""
1376 "fadd.d %0 = %1, %F2%B0"
1377 [(set_attr "type" "F")])
1378
1379(define_insn "subdf3"
1380 [(set (match_operand:DF 0 "register_operand" "=f")
1381 (minus:DF (match_operand:DF 1 "reg_or_fp01_operand" "fG")
1382 (match_operand:DF 2 "reg_or_fp01_operand" "fG")))]
1383 ""
1384 "fsub.d %0 = %F1, %F2%B0"
1385 [(set_attr "type" "F")])
1386
1387(define_insn "muldf3"
1388 [(set (match_operand:DF 0 "register_operand" "=f")
1389 (mult:DF (match_operand:DF 1 "register_operand" "f")
1390 (match_operand:DF 2 "register_operand" "f")))]
1391 ""
1392 "fmpy.d %0 = %1, %2%B0"
1393 [(set_attr "type" "F")])
1394
1395(define_insn "absdf2"
1396 [(set (match_operand:DF 0 "register_operand" "=f")
1397 (abs:DF (match_operand:DF 1 "register_operand" "f")))]
1398 ""
1399 "fabs %0 = %1%B0"
1400 [(set_attr "type" "F")])
1401
1402(define_insn "negdf2"
1403 [(set (match_operand:DF 0 "register_operand" "=f")
1404 (neg:DF (match_operand:DF 1 "register_operand" "f")))]
1405 ""
1406 "fneg %0 = %1%B0"
1407 [(set_attr "type" "F")])
1408
1409(define_insn "*nabsdf2"
1410 [(set (match_operand:DF 0 "register_operand" "=f")
1411 (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))]
1412 ""
1413 "fnegabs %0 = %1%B0"
1414 [(set_attr "type" "F")])
1415
1416(define_insn "mindf3"
1417 [(set (match_operand:DF 0 "register_operand" "=f")
1418 (smin:DF (match_operand:DF 1 "register_operand" "f")
1419 (match_operand:DF 2 "reg_or_fp01_operand" "fG")))]
1420 ""
1421 "fmin %0 = %1, %F2%B0"
1422 [(set_attr "type" "F")])
1423
1424(define_insn "maxdf3"
1425 [(set (match_operand:DF 0 "register_operand" "=f")
1426 (smax:DF (match_operand:DF 1 "register_operand" "f")
1427 (match_operand:DF 2 "reg_or_fp01_operand" "fG")))]
1428 ""
1429 "fmax %0 = %1, %F2%B0"
1430 [(set_attr "type" "F")])
1431
1432(define_insn "*madddf3"
1433 [(set (match_operand:DF 0 "register_operand" "=f")
1434 (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1435 (match_operand:DF 2 "register_operand" "f"))
1436 (match_operand:DF 3 "reg_or_fp01_operand" "fG")))]
1437 ""
1438 "fma.d %0 = %1, %2, %F3%B0"
1439 [(set_attr "type" "F")])
1440
1441(define_insn "*msubdf3"
1442 [(set (match_operand:DF 0 "register_operand" "=f")
1443 (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1444 (match_operand:DF 2 "register_operand" "f"))
1445 (match_operand:DF 3 "reg_or_fp01_operand" "fG")))]
1446 ""
1447 "fms.d %0 = %1, %2, %F3%B0"
1448 [(set_attr "type" "F")])
1449
1450(define_insn "*nmuldf3"
1451 [(set (match_operand:DF 0 "register_operand" "=f")
1452 (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1453 (match_operand:DF 2 "register_operand" "f"))))]
1454 ""
1455 "fnmpy.d %0 = %1, %2%B0"
1456 [(set_attr "type" "F")])
1457
1458;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
1459
1460(define_insn "*nmadddf3"
1461 [(set (match_operand:DF 0 "register_operand" "=f")
1462 (plus:DF (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1463 (match_operand:DF 2 "register_operand" "f")))
1464 (match_operand:DF 3 "reg_or_fp01_operand" "fG")))]
1465 ""
1466 "fnma.d %0 = %1, %2, %F3%B0"
1467 [(set_attr "type" "F")])
1468
1469\f
1470;; ::::::::::::::::::::
1471;; ::
1472;; :: 32 bit Integer Shifts and Rotates
1473;; ::
1474;; ::::::::::::::::::::
1475
1476;; There is no sign-extend form of dep, so we only get 32 bits of valid result
1477;; instead of 64 like the patterns below.
1478
1479;; Using a predicate that accepts only constants doesn't work, because optabs
1480;; will load the operand into a register and call the pattern if the predicate
1481;; did not accept it on the first try. So we use nonmemory_operand and then
1482;; verify that we have an appropriate constant in the expander.
1483
1484(define_expand "ashlsi3"
1485 [(set (match_operand:SI 0 "register_operand" "")
1486 (ashift:SI (match_operand:SI 1 "register_operand" "")
1487 (match_operand:SI 2 "nonmemory_operand" "")))]
1488 ""
1489 "
1490{
1491 if (! shift_32bit_count_operand (operands[2], SImode))
1492 FAIL;
1493}")
1494
1495(define_insn "*ashlsi3_internal"
1496 [(set (match_operand:SI 0 "register_operand" "=r")
1497 (ashift:SI (match_operand:SI 1 "register_operand" "r")
1498 (match_operand:SI 2 "shift_32bit_count_operand" "n")))]
1499 ""
1500 "dep.z %0 = %1, %2, %E2"
1501 [(set_attr "type" "I")])
1502
1503;; This is really an extract, but this is how combine canonicalizes the
1504;; operation.
1505
1506(define_expand "ashrsi3"
1507 [(set (match_dup 3)
1508 (ashiftrt:DI (sign_extend:DI
1509 (match_operand:SI 1 "register_operand" ""))
1510 (match_operand:DI 2 "nonmemory_operand" "")))
1511 (set (match_operand:SI 0 "register_operand" "") (match_dup 4))]
1512 ""
1513 "
1514{
1515 if (! shift_32bit_count_operand (operands[2], SImode))
1516 FAIL;
1517
1518 operands[3] = gen_reg_rtx (DImode);
1519 operands[4] = gen_lowpart (SImode, operands[3]);
1520}")
1521
1522(define_insn "*ashrsi3_internal"
1523 [(set (match_operand:DI 0 "register_operand" "=r")
1524 (ashiftrt:DI (sign_extend:DI
1525 (match_operand:SI 1 "register_operand" "r"))
1526 (match_operand:DI 2 "shift_32bit_count_operand" "n")))]
1527 ""
1528 "extr %0 = %1, %2, %E2"
1529 [(set_attr "type" "I")])
1530
1531;; This is really an extract, but this is how combine canonicalizes the
1532;; operation.
1533
1534(define_expand "lshrsi3"
1535 [(set (match_dup 3)
1536 (lshiftrt:DI (zero_extend:DI
1537 (match_operand:SI 1 "register_operand" ""))
1538 (match_operand:DI 2 "nonmemory_operand" "")))
1539 (set (match_operand:SI 0 "register_operand" "") (match_dup 4))]
1540 ""
1541 "
1542{
1543 if (! shift_32bit_count_operand (operands[2], SImode))
1544 FAIL;
1545
1546 operands[3] = gen_reg_rtx (DImode);
1547 operands[4] = gen_lowpart (SImode, operands[3]);
1548}")
1549
1550(define_insn "*lshrsi3_internal"
1551 [(set (match_operand:DI 0 "register_operand" "=r")
1552 (lshiftrt:DI (zero_extend:DI
1553 (match_operand:SI 1 "register_operand" "r"))
1554 (match_operand:DI 2 "shift_32bit_count_operand" "n")))]
1555 ""
1556 "extr.u %0 = %1, %2, %E2"
1557 [(set_attr "type" "I")])
1558
1559;; Use mix4.r/shr to implement rotrsi3. We only get 32 bits of valid result
1560;; here, instead of 64 like the patterns above.
1561
1562(define_expand "rotrsi3"
1563 [(set (match_dup 3)
1564 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
1565 (ashift:DI (zero_extend:DI (match_dup 1)) (const_int 32))))
1566 (set (match_dup 3)
1567 (lshiftrt:DI (match_dup 3)
1568 (match_operand:DI 2 "nonmemory_operand" "")))
1569 (set (match_operand:SI 0 "register_operand" "") (match_dup 4))]
1570 ""
1571 "
1572{
1573 if (! shift_32bit_count_operand (operands[2], SImode))
1574 FAIL;
1575
1576 operands[3] = gen_reg_rtx (DImode);
1577 operands[4] = gen_lowpart (SImode, operands[3]);
1578}")
1579
1580\f
1581;; ::::::::::::::::::::
1582;; ::
1583;; :: 64 bit Integer Shifts and Rotates
1584;; ::
1585;; ::::::::::::::::::::
1586
1587(define_insn "ashldi3"
1588 [(set (match_operand:DI 0 "register_operand" "=r")
1589 (ashift:DI (match_operand:DI 1 "register_operand" "r")
1590 (match_operand:DI 2 "reg_or_6bit_operand" "rM")))]
1591 ""
1592 "shl %0 = %1, %2"
1593 [(set_attr "type" "I")])
1594
1595;; ??? Maybe combine this with the multiply and add instruction?
1596
1597(define_insn "*shladd"
1598 [(set (match_operand:DI 0 "register_operand" "=r")
1599 (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "r")
1600 (match_operand:DI 2 "shladd_operand" "n"))
1601 (match_operand:DI 3 "register_operand" "r")))]
1602 ""
1603 "shladd %0 = %1, %S2, %3"
1604 [(set_attr "type" "A")])
1605
1606;; This can be created by register elimination if operand3 of shladd is an
1607;; eliminable register or has reg_equiv_constant set.
1608
1609;; We have to use nonmemory_operand for operand 4, to ensure that the
1610;; validate_changes call inside eliminate_regs will always succeed. If it
1611;; doesn't succeed, then this remain a shladd pattern, and will be reloaded
1612;; incorrectly.
1613
1614(define_insn "*shladd_elim"
1615 [(set (match_operand:DI 0 "register_operand" "=&r")
1616 (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "r")
1617 (match_operand:DI 2 "shladd_operand" "n"))
1618 (match_operand:DI 3 "register_operand" "r"))
1619 (match_operand:DI 4 "nonmemory_operand" "rI")))]
1620 "reload_in_progress"
1621 "#"
1622 [(set_attr "type" "unknown")])
1623
1624;; ??? Need to emit an instruction group barrier here because this gets split
1625;; after md_reorg.
1626
1627(define_split
1628 [(set (match_operand:DI 0 "register_operand" "")
1629 (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
1630 (match_operand:DI 2 "shladd_operand" ""))
1631 (match_operand:DI 3 "register_operand" ""))
1632 (match_operand:DI 4 "reg_or_14bit_operand" "")))]
1633 "reload_completed"
1634 [(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (match_dup 2))
1635 (match_dup 3)))
1636 (unspec_volatile [(const_int 0)] 2)
1637 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
1638 "")
1639
1640(define_insn "ashrdi3"
1641 [(set (match_operand:DI 0 "register_operand" "=r")
1642 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
1643 (match_operand:DI 2 "reg_or_6bit_operand" "rM")))]
1644 ""
1645 "shr %0 = %1, %2"
1646 [(set_attr "type" "I")])
1647
1648(define_insn "lshrdi3"
1649 [(set (match_operand:DI 0 "register_operand" "=r")
1650 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
1651 (match_operand:DI 2 "reg_or_6bit_operand" "rM")))]
1652 ""
1653 "shr.u %0 = %1, %2"
1654 [(set_attr "type" "I")])
1655
1656;; Using a predicate that accepts only constants doesn't work, because optabs
1657;; will load the operand into a register and call the pattern if the predicate
1658;; did not accept it on the first try. So we use nonmemory_operand and then
1659;; verify that we have an appropriate constant in the expander.
1660
1661(define_expand "rotrdi3"
1662 [(set (match_operand:DI 0 "register_operand" "")
1663 (rotatert:DI (match_operand:DI 1 "register_operand" "")
1664 (match_operand:DI 2 "nonmemory_operand" "")))]
1665 ""
1666 "
1667{
1668 if (! shift_count_operand (operands[2], DImode))
1669 FAIL;
1670}")
1671
1672(define_insn "*rotrdi3_internal"
1673 [(set (match_operand:DI 0 "register_operand" "=r")
1674 (rotatert:DI (match_operand:DI 1 "register_operand" "r")
1675 (match_operand:DI 2 "shift_count_operand" "M")))]
1676 ""
1677 "shrp %0 = %1, %1, %2"
1678 [(set_attr "type" "I")])
1679
1680\f
1681;; ::::::::::::::::::::
1682;; ::
1683;; :: 32 Bit Integer Logical operations
1684;; ::
1685;; ::::::::::::::::::::
1686
1687;; We don't seem to need any other 32-bit logical operations, because gcc
1688;; generates zero-extend;zero-extend;DImode-op, which combine optimizes to
1689;; DImode-op;zero-extend, and then we can optimize away the zero-extend.
1690;; This doesn't work for unary logical operations, because we don't call
1691;; apply_distributive_law for them.
1692
1693;; ??? Likewise, this doesn't work for andnot, which isn't handled by
1694;; apply_distributive_law. We get inefficient code for
1695;; int sub4 (int i, int j) { return i & ~j; }
1696;; We could convert (and (not (sign_extend A)) (sign_extend B)) to
1697;; (zero_extend (and (not A) B)) in combine.
1698;; Or maybe fix this by adding andsi3/iorsi3/xorsi3 patterns like the
1699;; one_cmplsi2 pattern.
1700
1701(define_expand "one_cmplsi2"
1702 [(set (match_operand:SI 0 "register_operand" "")
1703 (not:SI (match_operand:SI 1 "register_operand" "")))]
1704 ""
1705 "
1706{
1707 if (optimize)
1708 {
1709 rtx op1 = gen_lowpart (DImode, operands[1]);
1710
1711 if (! cse_not_expected)
1712 {
1713 rtx tmp = gen_reg_rtx (DImode);
1714 emit_insn (gen_one_cmpldi2 (tmp, op1));
1715 emit_move_insn (operands[0], gen_lowpart (SImode, tmp));
1716 }
1717 else
1718 emit_insn (gen_one_cmpldi2 (gen_lowpart (DImode, operands[0]), op1));
1719 DONE;
1720 }
1721}")
1722
1723(define_insn "*one_cmplsi2_internal"
1724 [(set (match_operand:SI 0 "register_operand" "=r")
1725 (not:SI (match_operand:SI 1 "register_operand" "r")))]
1726 ""
1727 "andcm %0 = -1, %1"
1728 [(set_attr "type" "A")])
1729
1730\f
1731;; ::::::::::::::::::::
1732;; ::
1733;; :: 64 Bit Integer Logical operations
1734;; ::
1735;; ::::::::::::::::::::
1736
1737(define_insn "anddi3"
1738 [(set (match_operand:DI 0 "register_operand" "=r,*e")
1739 (and:DI (match_operand:DI 1 "register_operand" "%r,*e")
1740 (match_operand:DI 2 "reg_or_8bit_operand" "rK,*e")))]
1741 ""
1742 "@
1743 and %0 = %2, %1
1744 fand %0 = %2, %1%B0"
1745 [(set_attr "type" "A,F")])
1746
1747(define_insn "*andnot"
1748 [(set (match_operand:DI 0 "register_operand" "=r,*e")
1749 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,*e"))
1750 (match_operand:DI 2 "reg_or_8bit_operand" "rK,*e")))]
1751 ""
1752 "@
1753 andcm %0 = %2, %1
1754 fandcm %0 = %2, %1%B0"
1755 [(set_attr "type" "A,F")])
1756
1757(define_insn "iordi3"
1758 [(set (match_operand:DI 0 "register_operand" "=r,*e")
1759 (ior:DI (match_operand:DI 1 "register_operand" "%r,*e")
1760 (match_operand:DI 2 "reg_or_8bit_operand" "rK,*e")))]
1761 ""
1762 "@
1763 or %0 = %2, %1
1764 for %0 = %2, %1%B0"
1765 [(set_attr "type" "A,F")])
1766
1767(define_insn "xordi3"
1768 [(set (match_operand:DI 0 "register_operand" "=r,*e")
1769 (xor:DI (match_operand:DI 1 "register_operand" "%r,*e")
1770 (match_operand:DI 2 "reg_or_8bit_operand" "rK,*e")))]
1771 ""
1772 "@
1773 xor %0 = %2, %1
1774 fxor %0 = %2, %1%B0"
1775 [(set_attr "type" "A,F")])
1776
1777(define_insn "one_cmpldi2"
1778 [(set (match_operand:DI 0 "register_operand" "=r")
1779 (not:DI (match_operand:DI 1 "register_operand" "r")))]
1780 ""
1781 "andcm %0 = -1, %1"
1782 [(set_attr "type" "A")])
1783\f
1784;; ::::::::::::::::::::
1785;; ::
1786;; :: Comparisons
1787;; ::
1788;; ::::::::::::::::::::
1789
1790(define_expand "cmpsi"
1791 [(set (cc0)
1792 (compare (match_operand:SI 0 "register_operand" "")
1793 (match_operand:SI 1 "reg_or_8bit_and_adjusted_operand" "")))]
1794 ""
1795 "
1796{
1797 ia64_compare_op0 = operands[0];
1798 ia64_compare_op1 = operands[1];
1799 DONE;
1800}")
1801
1802(define_expand "cmpdi"
1803 [(set (cc0)
1804 (compare (match_operand:DI 0 "register_operand" "")
1805 (match_operand:DI 1 "reg_or_8bit_and_adjusted_operand" "")))]
1806 ""
1807 "
1808{
1809 ia64_compare_op0 = operands[0];
1810 ia64_compare_op1 = operands[1];
1811 DONE;
1812}")
1813
1814(define_expand "cmpsf"
1815 [(set (cc0)
1816 (compare (match_operand:SF 0 "reg_or_fp01_operand" "")
1817 (match_operand:SF 1 "reg_or_fp01_operand" "")))]
1818 ""
1819 "
1820{
1821 ia64_compare_op0 = operands[0];
1822 ia64_compare_op1 = operands[1];
1823 DONE;
1824}")
1825
1826(define_expand "cmpdf"
1827 [(set (cc0)
1828 (compare (match_operand:DF 0 "reg_or_fp01_operand" "")
1829 (match_operand:DF 1 "reg_or_fp01_operand" "")))]
1830 ""
1831 "
1832{
1833 ia64_compare_op0 = operands[0];
1834 ia64_compare_op1 = operands[1];
1835 DONE;
1836}")
1837
1838;; ??? Enable this for XFmode support.
1839
1840(define_expand "cmpxf"
1841 [(set (cc0)
1842 (compare (match_operand:XF 0 "reg_or_fp01_operand" "")
1843 (match_operand:XF 1 "reg_or_fp01_operand" "")))]
1844 "0"
1845 "
1846{
1847 ia64_compare_op0 = operands[0];
1848 ia64_compare_op1 = operands[1];
1849 DONE;
1850}")
1851
1852(define_insn "*cmpsi_normal"
1853 [(set (match_operand:CC 0 "register_operand" "=c")
1854 (match_operator:CC 1 "normal_comparison_operator"
1855 [(match_operand:SI 2 "register_operand" "r")
1856 (match_operand:SI 3 "reg_or_8bit_operand" "rK")]))]
1857 ""
1858 "cmp4.%C1 %0, %I0 = %3, %2"
1859 [(set_attr "type" "A")])
1860
1861(define_insn "*cmpsi_adjusted"
1862 [(set (match_operand:CC 0 "register_operand" "=c")
1863 (match_operator:CC 1 "adjusted_comparison_operator"
1864 [(match_operand:SI 2 "register_operand" "r")
1865 (match_operand:SI 3 "reg_or_8bit_adjusted_operand"
1866 "rL")]))]
1867 ""
1868 "cmp4.%C1 %0, %I0 = %3, %2"
1869 [(set_attr "type" "A")])
1870
1871(define_insn "*cmpdi_normal"
1872 [(set (match_operand:CC 0 "register_operand" "=c")
1873 (match_operator:CC 1 "normal_comparison_operator"
1874 [(match_operand:DI 2 "register_operand" "r")
1875 (match_operand:DI 3 "reg_or_8bit_operand" "rK")]))]
1876 ""
1877 "cmp.%C1 %0, %I0 = %3, %2"
1878 [(set_attr "type" "A")])
1879
1880(define_insn "*cmpdi_adjusted"
1881 [(set (match_operand:CC 0 "register_operand" "=c")
1882 (match_operator:CC 1 "adjusted_comparison_operator"
1883 [(match_operand:DI 2 "register_operand" "r")
1884 (match_operand:DI 3 "reg_or_8bit_adjusted_operand"
1885 "rL")]))]
1886 ""
1887 "cmp.%C1 %0, %I0 = %3, %2"
1888 [(set_attr "type" "A")])
1889
1890(define_insn "*cmpsf_internal"
1891 [(set (match_operand:CC 0 "register_operand" "=c")
1892 (match_operator:CC 1 "comparison_operator"
1893 [(match_operand:SF 2 "reg_or_fp01_operand" "fG")
1894 (match_operand:SF 3 "reg_or_fp01_operand" "fG")]))]
1895 ""
1896 "fcmp.%D1 %0, %I0 = %F2, %F3"
1897 [(set_attr "type" "F")])
1898
1899(define_insn "*cmpdf_internal"
1900 [(set (match_operand:CC 0 "register_operand" "=c")
1901 (match_operator:CC 1 "comparison_operator"
1902 [(match_operand:DF 2 "reg_or_fp01_operand" "fG")
1903 (match_operand:DF 3 "reg_or_fp01_operand" "fG")]))]
1904 ""
1905 "fcmp.%D1 %0, %I0 = %F2, %F3"
1906 [(set_attr "type" "F")])
1907
1908;; ??? Can this pattern be generated?
1909
1910(define_insn "*bit_zero"
1911 [(set (match_operand:CC 0 "register_operand" "=c")
1912 (eq:CC (zero_extract:DI (match_operand:DI 1 "register_operand" "r")
1913 (const_int 1)
1914 (match_operand:DI 2 "immediate_operand" "n"))
1915 (const_int 0)))]
1916 ""
1917 "tbit.z %0, %I0 = %1, %2"
1918 [(set_attr "type" "I")])
1919
1920(define_insn "*bit_one"
1921 [(set (match_operand:CC 0 "register_operand" "=c")
1922 (ne:CC (zero_extract:DI (match_operand:DI 1 "register_operand" "r")
1923 (const_int 1)
1924 (match_operand:DI 2 "immediate_operand" "n"))
1925 (const_int 0)))]
1926 ""
1927 "tbit.nz %0, %I0 = %1, %2"
1928 [(set_attr "type" "I")])
1929
1930;; ??? We also need this if we run out of PR regs and need to spill some.
1931
1932;; ??? We need this if a CCmode value does not get allocated to a hard
1933;; register. This happens if we cse/gcse a CCmode value across a call, and the
1934;; function has a nonlocal goto. This is because global does not allocate
1935;; call crossing pseudos to hard registers when current_function_has_
1936;; nonlocal_goto is true. This is relatively common for C++ programs that
1937;; use exceptions. See ia64_secondary_reload_class.
1938
1939;; We use a define_expand here so that cse/gcse/combine can't accidentally
1940;; create movcc insns. If this was a named define_insn, we would not be able
1941;; to make it conditional on reload.
1942
1943(define_expand "movcc"
1944 [(set (match_operand:CC 0 "nonimmediate_operand" "")
1945 (match_operand:CC 1 "move_operand" ""))]
1946 ""
1947 "
1948{
1949 if (! reload_in_progress && ! reload_completed)
1950 FAIL;
1951}")
1952
1953(define_insn "*movcc_internal"
1954 [(set (match_operand:CC 0 "nonimmediate_operand" "=r,c,r,m")
1955 (match_operand:CC 1 "move_operand" "c,r,m,r"))]
1956 "reload_in_progress || reload_completed"
1957 "@
1958 #
1959 cmp4.ne %0, %I0 = %1, r0
1960 ld4%O1 %0 = %1%P1
1961 st4%Q0 %0 = %1%P0"
1962 [(set_attr "type" "unknown,A,M,M")])
1963
1964(define_split
1965 [(set (match_operand:CC 0 "register_operand" "")
1966 (match_operand:CC 1 "register_operand" ""))]
1967 "reload_completed
1968 && GET_CODE (operands[0]) == REG && GR_REGNO_P (REGNO (operands[0]))
1969 && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
1970 [(set (match_dup 2)
1971 (if_then_else:DI (ne:CC (match_dup 1) (const_int 0))
1972 (const_int 1)
1973 (match_dup 2)))
1974 (set (match_dup 2)
1975 (if_then_else:DI (ne:CC (match_dup 1) (const_int 0))
1976 (match_dup 2)
1977 (const_int 0)))]
1978 "operands[2] = gen_rtx_SUBREG (DImode, operands[0], 0);")
1979
1980\f
1981;; ::::::::::::::::::::
1982;; ::
1983;; :: Branches
1984;; ::
1985;; ::::::::::::::::::::
1986
1987(define_expand "beq"
1988 [(set (match_dup 1)
1989 (eq:CC (match_dup 2)
1990 (match_dup 3)))
1991 (set (pc)
1992 (if_then_else (ne:CC (match_dup 1)
1993 (const_int 0))
1994 (label_ref (match_operand 0 "" ""))
1995 (pc)))]
1996 ""
1997 "
1998{
1999 operands[1] = gen_reg_rtx (CCmode);
2000 operands[2] = ia64_compare_op0;
2001 operands[3] = ia64_compare_op1;
2002}")
2003
2004(define_expand "bne"
2005 [(set (match_dup 1)
2006 (ne:CC (match_dup 2)
2007 (match_dup 3)))
2008 (set (pc)
2009 (if_then_else (ne:CC (match_dup 1)
2010 (const_int 0))
2011 (label_ref (match_operand 0 "" ""))
2012 (pc)))]
2013 ""
2014 "
2015{
2016 operands[1] = gen_reg_rtx (CCmode);
2017 operands[2] = ia64_compare_op0;
2018 operands[3] = ia64_compare_op1;
2019}")
2020
2021(define_expand "blt"
2022 [(set (match_dup 1)
2023 (lt:CC (match_dup 2)
2024 (match_dup 3)))
2025 (set (pc)
2026 (if_then_else (ne:CC (match_dup 1)
2027 (const_int 0))
2028 (label_ref (match_operand 0 "" ""))
2029 (pc)))]
2030 ""
2031 "
2032{
2033 operands[1] = gen_reg_rtx (CCmode);
2034 operands[2] = ia64_compare_op0;
2035 operands[3] = ia64_compare_op1;
2036}")
2037
2038(define_expand "ble"
2039 [(set (match_dup 1)
2040 (le:CC (match_dup 2)
2041 (match_dup 3)))
2042 (set (pc)
2043 (if_then_else (ne:CC (match_dup 1)
2044 (const_int 0))
2045 (label_ref (match_operand 0 "" ""))
2046 (pc)))]
2047 ""
2048 "
2049{
2050 operands[1] = gen_reg_rtx (CCmode);
2051 operands[2] = ia64_compare_op0;
2052 operands[3] = ia64_compare_op1;
2053}")
2054
2055(define_expand "bgt"
2056 [(set (match_dup 1)
2057 (gt:CC (match_dup 2)
2058 (match_dup 3)))
2059 (set (pc)
2060 (if_then_else (ne:CC (match_dup 1)
2061 (const_int 0))
2062 (label_ref (match_operand 0 "" ""))
2063 (pc)))]
2064 ""
2065 "
2066{
2067 operands[1] = gen_reg_rtx (CCmode);
2068 operands[2] = ia64_compare_op0;
2069 operands[3] = ia64_compare_op1;
2070}")
2071
2072(define_expand "bge"
2073 [(set (match_dup 1)
2074 (ge:CC (match_dup 2)
2075 (match_dup 3)))
2076 (set (pc)
2077 (if_then_else (ne:CC (match_dup 1)
2078 (const_int 0))
2079 (label_ref (match_operand 0 "" ""))
2080 (pc)))]
2081 ""
2082 "
2083{
2084 operands[1] = gen_reg_rtx (CCmode);
2085 operands[2] = ia64_compare_op0;
2086 operands[3] = ia64_compare_op1;
2087}")
2088
2089(define_expand "bltu"
2090 [(set (match_dup 1)
2091 (ltu:CC (match_dup 2)
2092 (match_dup 3)))
2093 (set (pc)
2094 (if_then_else (ne:CC (match_dup 1)
2095 (const_int 0))
2096 (label_ref (match_operand 0 "" ""))
2097 (pc)))]
2098 ""
2099 "
2100{
2101 operands[1] = gen_reg_rtx (CCmode);
2102 operands[2] = ia64_compare_op0;
2103 operands[3] = ia64_compare_op1;
2104}")
2105
2106(define_expand "bleu"
2107 [(set (match_dup 1)
2108 (leu:CC (match_dup 2)
2109 (match_dup 3)))
2110 (set (pc)
2111 (if_then_else (ne:CC (match_dup 1)
2112 (const_int 0))
2113 (label_ref (match_operand 0 "" ""))
2114 (pc)))]
2115 ""
2116 "
2117{
2118 operands[1] = gen_reg_rtx (CCmode);
2119 operands[2] = ia64_compare_op0;
2120 operands[3] = ia64_compare_op1;
2121}")
2122
2123(define_expand "bgtu"
2124 [(set (match_dup 1)
2125 (gtu:CC (match_dup 2)
2126 (match_dup 3)))
2127 (set (pc)
2128 (if_then_else (ne:CC (match_dup 1)
2129 (const_int 0))
2130 (label_ref (match_operand 0 "" ""))
2131 (pc)))]
2132 ""
2133 "
2134{
2135 operands[1] = gen_reg_rtx (CCmode);
2136 operands[2] = ia64_compare_op0;
2137 operands[3] = ia64_compare_op1;
2138}")
2139
2140(define_expand "bgeu"
2141 [(set (match_dup 1)
2142 (geu:CC (match_dup 2)
2143 (match_dup 3)))
2144 (set (pc)
2145 (if_then_else (ne:CC (match_dup 1)
2146 (const_int 0))
2147 (label_ref (match_operand 0 "" ""))
2148 (pc)))]
2149 ""
2150 "
2151{
2152 operands[1] = gen_reg_rtx (CCmode);
2153 operands[2] = ia64_compare_op0;
2154 operands[3] = ia64_compare_op1;
2155}")
2156
6b6c1201 2157(define_insn "*br_true"
c65ebc55 2158 [(set (pc)
6b6c1201
RH
2159 (if_then_else (match_operator 0 "predicate_operator"
2160 [(match_operand:CC 1 "register_operand" "c")
2161 (const_int 0)])
2162 (label_ref (match_operand 2 "" ""))
c65ebc55
JW
2163 (pc)))]
2164 ""
85548039 2165 "(%J0) br.cond%+ %l2"
e5bde68a
RH
2166 [(set_attr "type" "B")
2167 (set_attr "predicable" "no")])
c65ebc55 2168
6b6c1201 2169(define_insn "*br_false"
c65ebc55 2170 [(set (pc)
6b6c1201
RH
2171 (if_then_else (match_operator 0 "predicate_operator"
2172 [(match_operand:CC 1 "register_operand" "c")
2173 (const_int 0)])
c65ebc55 2174 (pc)
6b6c1201 2175 (label_ref (match_operand 2 "" ""))))]
c65ebc55 2176 ""
85548039 2177 "(%j0) br.cond%+ %l2"
e5bde68a
RH
2178 [(set_attr "type" "B")
2179 (set_attr "predicable" "no")])
c65ebc55
JW
2180\f
2181;; ::::::::::::::::::::
2182;; ::
2183;; :: Set flag operations
2184;; ::
2185;; ::::::::::::::::::::
2186
2187(define_expand "seq"
2188 [(set (match_dup 1)
2189 (eq:CC (match_dup 2)
2190 (match_dup 3)))
2191 (set (match_operand:DI 0 "register_operand" "")
2192 (ne:DI (match_dup 1) (const_int 0)))]
2193 ""
2194 "
2195{
2196 operands[1] = gen_reg_rtx (CCmode);
2197 operands[2] = ia64_compare_op0;
2198 operands[3] = ia64_compare_op1;
2199}")
2200
2201(define_expand "sne"
2202 [(set (match_dup 1)
2203 (ne:CC (match_dup 2)
2204 (match_dup 3)))
2205 (set (match_operand:DI 0 "register_operand" "")
2206 (ne:DI (match_dup 1) (const_int 0)))]
2207 ""
2208 "
2209{
2210 operands[1] = gen_reg_rtx (CCmode);
2211 operands[2] = ia64_compare_op0;
2212 operands[3] = ia64_compare_op1;
2213}")
2214
2215(define_expand "slt"
2216 [(set (match_dup 1)
2217 (lt:CC (match_dup 2)
2218 (match_dup 3)))
2219 (set (match_operand:DI 0 "register_operand" "")
2220 (ne:DI (match_dup 1) (const_int 0)))]
2221 ""
2222 "
2223{
2224 operands[1] = gen_reg_rtx (CCmode);
2225 operands[2] = ia64_compare_op0;
2226 operands[3] = ia64_compare_op1;
2227}")
2228
2229(define_expand "sle"
2230 [(set (match_dup 1)
2231 (le:CC (match_dup 2)
2232 (match_dup 3)))
2233 (set (match_operand:DI 0 "register_operand" "")
2234 (ne:DI (match_dup 1) (const_int 0)))]
2235 ""
2236 "
2237{
2238 operands[1] = gen_reg_rtx (CCmode);
2239 operands[2] = ia64_compare_op0;
2240 operands[3] = ia64_compare_op1;
2241}")
2242
2243(define_expand "sgt"
2244 [(set (match_dup 1)
2245 (gt:CC (match_dup 2)
2246 (match_dup 3)))
2247 (set (match_operand:DI 0 "register_operand" "")
2248 (ne:DI (match_dup 1) (const_int 0)))]
2249 ""
2250 "
2251{
2252 operands[1] = gen_reg_rtx (CCmode);
2253 operands[2] = ia64_compare_op0;
2254 operands[3] = ia64_compare_op1;
2255}")
2256
2257(define_expand "sge"
2258 [(set (match_dup 1)
2259 (ge:CC (match_dup 2)
2260 (match_dup 3)))
2261 (set (match_operand:DI 0 "register_operand" "")
2262 (ne:DI (match_dup 1) (const_int 0)))]
2263 ""
2264 "
2265{
2266 operands[1] = gen_reg_rtx (CCmode);
2267 operands[2] = ia64_compare_op0;
2268 operands[3] = ia64_compare_op1;
2269}")
2270
2271(define_expand "sltu"
2272 [(set (match_dup 1)
2273 (ltu:CC (match_dup 2)
2274 (match_dup 3)))
2275 (set (match_operand:DI 0 "register_operand" "")
2276 (ne:DI (match_dup 1) (const_int 0)))]
2277 ""
2278 "
2279{
2280 operands[1] = gen_reg_rtx (CCmode);
2281 operands[2] = ia64_compare_op0;
2282 operands[3] = ia64_compare_op1;
2283}")
2284
2285(define_expand "sleu"
2286 [(set (match_dup 1)
2287 (leu:CC (match_dup 2)
2288 (match_dup 3)))
2289 (set (match_operand:DI 0 "register_operand" "")
2290 (ne:DI (match_dup 1) (const_int 0)))]
2291 ""
2292 "
2293{
2294 operands[1] = gen_reg_rtx (CCmode);
2295 operands[2] = ia64_compare_op0;
2296 operands[3] = ia64_compare_op1;
2297}")
2298
2299(define_expand "sgtu"
2300 [(set (match_dup 1)
2301 (gtu:CC (match_dup 2)
2302 (match_dup 3)))
2303 (set (match_operand:DI 0 "register_operand" "")
2304 (ne:DI (match_dup 1) (const_int 0)))]
2305 ""
2306 "
2307{
2308 operands[1] = gen_reg_rtx (CCmode);
2309 operands[2] = ia64_compare_op0;
2310 operands[3] = ia64_compare_op1;
2311}")
2312
2313(define_expand "sgeu"
2314 [(set (match_dup 1)
2315 (geu:CC (match_dup 2)
2316 (match_dup 3)))
2317 (set (match_operand:DI 0 "register_operand" "")
2318 (ne:DI (match_dup 1) (const_int 0)))]
2319 ""
2320 "
2321{
2322 operands[1] = gen_reg_rtx (CCmode);
2323 operands[2] = ia64_compare_op0;
2324 operands[3] = ia64_compare_op1;
2325}")
2326
2327;; Don't allow memory as destination here, because cmov/cmov/st is more
2328;; efficient than mov/mov/cst/cst.
2329
2330(define_insn "*sne_internal"
2331 [(set (match_operand:DI 0 "register_operand" "=r")
2332 (ne:DI (match_operand:CC 1 "register_operand" "c")
2333 (const_int 0)))]
2334 ""
2335 "#"
2336 [(set_attr "type" "unknown")])
2337
2338(define_split
2339 [(set (match_operand:DI 0 "register_operand" "")
2340 (ne:DI (match_operand:CC 1 "register_operand" "")
2341 (const_int 0)))]
2342 "reload_completed"
2343 [(set (match_dup 0)
2344 (if_then_else:DI (ne:CC (match_dup 1) (const_int 0))
2345 (const_int 1)
2346 (match_dup 0)))
2347 (set (match_dup 0)
2348 (if_then_else:DI (ne:CC (match_dup 1) (const_int 0))
2349 (match_dup 0)
2350 (const_int 0)))]
2351 "")
2352
2353;; ??? Unknown if this can be matched.
2354
2355(define_insn "*seq_internal"
2356 [(set (match_operand:DI 0 "register_operand" "=r")
2357 (eq:DI (match_operand:CC 1 "register_operand" "c")
2358 (const_int 0)))]
2359 ""
2360 "#"
2361 [(set_attr "type" "unknown")])
2362
2363;; ??? Unknown if this can be matched.
2364
2365(define_split
2366 [(set (match_operand:DI 0 "register_operand" "")
2367 (eq:DI (match_operand:CC 1 "register_operand" "")
2368 (const_int 0)))]
2369 "reload_completed"
2370 [(set (match_dup 0)
2371 (if_then_else:DI (eq:CC (match_dup 1) (const_int 0))
2372 (const_int 1)
2373 (match_dup 0)))
2374 (set (match_dup 0)
2375 (if_then_else:DI (eq:CC (match_dup 1) (const_int 0))
2376 (match_dup 0)
2377 (const_int 0)))]
2378 "")
2379
2380\f
2381;; ::::::::::::::::::::
2382;; ::
2383;; :: Conditional move instructions.
2384;; ::
2385;; ::::::::::::::::::::
2386
2387;; ??? Add movXXcc patterns?
2388
2389;; ??? The predicates don't match the constraints.
2390
2391;; ??? r/c/m/m and m/c/r/r alternatives make sense, but won't work until the
2392;; predicates are fixed, because the define_splits won't recognize them.
2393
2394;;
2395;; DImode if_then_else patterns.
2396;;
2397
e5bde68a 2398(define_insn "*cmovdi_internal"
c65ebc55 2399 [(set (match_operand:DI 0 "register_operand" "=r,r,m,r,r,m,r")
e5bde68a
RH
2400 (if_then_else:DI
2401 (match_operator:CC 4 "predicate_operator"
2402 [(match_operand:CC 1 "register_operand" "c,c,c,c,c,c,c")
2403 (const_int 0)])
2404 (match_operand:DI 2 "reg_or_22bit_operand" "0,0,0,rI,m,r,rI")
2405 (match_operand:DI 3 "reg_or_22bit_operand" "rI,m,r,0,0,0,rI")))]
c65ebc55 2406 ""
e5bde68a 2407 "#"
c65ebc55
JW
2408 [(set_attr "type" "A,M,M,A,M,M,unknown")])
2409
2410(define_split
2411 [(set (match_operand:DI 0 "register_operand" "")
e5bde68a
RH
2412 (if_then_else:DI
2413 (match_operator:CC 4 "predicate_operator"
2414 [(match_operand:CC 1 "register_operand" "")
2415 (const_int 0)])
2416 (match_operand:DI 2 "reg_or_22bit_operand" "")
2417 (match_operand:DI 3 "reg_or_22bit_operand" "")))]
c65ebc55 2418 "(reload_completed
e5bde68a
RH
2419 && (rtx_equal_p (operands[0], operands[2])
2420 || rtx_equal_p (operands[0], operands[3])))"
2421 [(cond_exec
2422 (match_dup 4)
2423 (set (match_dup 0) (match_dup 2)))]
2424 "
2425{
2426 if (rtx_equal_p (operands[0], operands[2]))
2427 {
2428 operands[2] = operands[3];
2429 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
2430 CCmode, operands[1], const0_rtx);
2431 }
2432}")
c65ebc55
JW
2433
2434(define_split
2435 [(set (match_operand:DI 0 "register_operand" "")
e5bde68a
RH
2436 (if_then_else:DI
2437 (match_operator:CC 4 "predicate_operator"
2438 [(match_operand:CC 1 "register_operand" "")
2439 (const_int 0)])
2440 (match_operand:DI 2 "reg_or_22bit_operand" "")
2441 (match_operand:DI 3 "reg_or_22bit_operand" "")))]
2442 "reload_completed"
2443 [(cond_exec
2444 (match_dup 4)
2445 (set (match_dup 0) (match_dup 2)))
2446 (cond_exec
2447 (match_dup 5)
2448 (set (match_dup 0) (match_dup 3)))]
2449 "
2450{
2451 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
2452 CCmode, operands[1], const0_rtx);
2453}")
c65ebc55
JW
2454
2455;; Absolute value pattern.
2456
2457(define_insn "*absdi2_internal"
2458 [(set (match_operand:DI 0 "register_operand" "=r,r")
e5bde68a
RH
2459 (if_then_else:DI
2460 (match_operator:CC 4 "predicate_operator"
2461 [(match_operand:CC 1 "register_operand" "c,c")
2462 (const_int 0)])
2463 (neg:DI (match_operand:DI 2 "reg_or_22bit_operand" "rI,rI"))
2464 (match_operand:DI 3 "reg_or_22bit_operand" "0,rI")))]
c65ebc55 2465 ""
e5bde68a 2466 "#"
c65ebc55
JW
2467 [(set_attr "type" "A,unknown")])
2468
2469(define_split
2470 [(set (match_operand:DI 0 "register_operand" "")
e5bde68a
RH
2471 (if_then_else:DI
2472 (match_operator:CC 4 "predicate_operator"
2473 [(match_operand:CC 1 "register_operand" "c,c")
2474 (const_int 0)])
2475 (neg:DI (match_operand:DI 2 "reg_or_22bit_operand" ""))
2476 (match_operand:DI 3 "reg_or_22bit_operand" "")))]
2477 "reload_completed && rtx_equal_p (operands[0], operands[3])"
2478 [(cond_exec
2479 (match_dup 4)
2480 (set (match_dup 0)
2481 (neg:DI (match_dup 2))))]
c65ebc55
JW
2482 "")
2483
e5bde68a
RH
2484(define_split
2485 [(set (match_operand:DI 0 "register_operand" "")
2486 (if_then_else:DI
2487 (match_operator:CC 4 "predicate_operator"
2488 [(match_operand:CC 1 "register_operand" "c,c")
2489 (const_int 0)])
2490 (neg:DI (match_operand:DI 2 "reg_or_22bit_operand" ""))
2491 (match_operand:DI 3 "reg_or_22bit_operand" "")))]
2492 "reload_completed"
2493 [(cond_exec
2494 (match_dup 4)
2495 (set (match_dup 0) (neg:DI (match_dup 2))))
2496 (cond_exec
2497 (match_dup 5)
2498 (set (match_dup 0) (match_dup 3)))]
2499 "
2500{
2501 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
2502 CCmode, operands[1], const0_rtx);
2503}")
c65ebc55
JW
2504
2505;;
2506;; SImode if_then_else patterns.
2507;;
2508
e5bde68a 2509(define_insn "*cmovsi_internal"
c65ebc55 2510 [(set (match_operand:SI 0 "register_operand" "=r,r,m,r,r,m,r")
e5bde68a
RH
2511 (if_then_else:SI
2512 (match_operator:CC 4 "predicate_operator"
2513 [(match_operand:CC 1 "register_operand" "c,c,c,c,c,c,c")
2514 (const_int 0)])
2515 (match_operand:SI 2 "reg_or_22bit_operand" "0,0,0,rI,m,r,rI")
2516 (match_operand:SI 3 "reg_or_22bit_operand" "rI,m,r,0,0,0,rI")))]
c65ebc55 2517 ""
e5bde68a 2518 "#"
c65ebc55
JW
2519 [(set_attr "type" "A,M,M,A,M,M,unknown")])
2520
2521(define_split
2522 [(set (match_operand:SI 0 "register_operand" "")
e5bde68a
RH
2523 (if_then_else:SI
2524 (match_operator:CC 4 "predicate_operator"
2525 [(match_operand:CC 1 "register_operand" "")
2526 (const_int 0)])
2527 (match_operand:SI 2 "reg_or_22bit_operand" "")
2528 (match_operand:SI 3 "reg_or_22bit_operand" "")))]
c65ebc55 2529 "(reload_completed
e5bde68a
RH
2530 && (rtx_equal_p (operands[0], operands[2])
2531 || rtx_equal_p (operands[0], operands[3])))"
2532 [(cond_exec
2533 (match_dup 4)
2534 (set (match_dup 0) (match_dup 2)))]
2535 "
2536{
2537 if (rtx_equal_p (operands[0], operands[2]))
2538 {
2539 operands[2] = operands[3];
2540 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
2541 CCmode, operands[1], const0_rtx);
2542 }
2543}")
2544
2545(define_split
2546 [(set (match_operand:SI 0 "register_operand" "")
2547 (if_then_else:SI
2548 (match_operator:CC 4 "predicate_operator"
2549 [(match_operand:CC 1 "register_operand" "")
2550 (const_int 0)])
2551 (match_operand:SI 2 "reg_or_22bit_operand" "")
2552 (match_operand:SI 3 "reg_or_22bit_operand" "")))]
2553 "reload_completed"
2554 [(cond_exec
2555 (match_dup 4)
2556 (set (match_dup 0) (match_dup 2)))
2557 (cond_exec
2558 (match_dup 5)
2559 (set (match_dup 0) (match_dup 3)))]
2560 "
2561{
2562 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
2563 CCmode, operands[1], const0_rtx);
2564}")
c65ebc55
JW
2565
2566(define_insn "*abssi2_internal"
2567 [(set (match_operand:SI 0 "register_operand" "=r,r")
e5bde68a
RH
2568 (if_then_else:SI
2569 (match_operator:CC 4 "predicate_operator"
2570 [(match_operand:CC 1 "register_operand" "c,c")
2571 (const_int 0)])
2572 (neg:SI (match_operand:SI 3 "reg_or_22bit_operand" "rI,rI"))
2573 (match_operand:SI 2 "reg_or_22bit_operand" "0,rI")))]
c65ebc55 2574 ""
e5bde68a 2575 "#"
c65ebc55
JW
2576 [(set_attr "type" "A,unknown")])
2577
2578(define_split
2579 [(set (match_operand:SI 0 "register_operand" "")
e5bde68a
RH
2580 (if_then_else:SI
2581 (match_operator:CC 4 "predicate_operator"
2582 [(match_operand:CC 1 "register_operand" "c,c")
2583 (const_int 0)])
2584 (neg:SI (match_operand:SI 2 "reg_or_22bit_operand" ""))
2585 (match_operand:SI 3 "reg_or_22bit_operand" "")))]
2586 "reload_completed && rtx_equal_p (operands[0], operands[3])"
2587 [(cond_exec
2588 (match_dup 4)
2589 (set (match_dup 0)
2590 (neg:SI (match_dup 2))))]
c65ebc55
JW
2591 "")
2592
e5bde68a
RH
2593(define_split
2594 [(set (match_operand:SI 0 "register_operand" "")
2595 (if_then_else:SI
2596 (match_operator:CC 4 "predicate_operator"
2597 [(match_operand:CC 1 "register_operand" "c,c")
2598 (const_int 0)])
2599 (neg:SI (match_operand:SI 2 "reg_or_22bit_operand" ""))
2600 (match_operand:SI 3 "reg_or_22bit_operand" "")))]
2601 "reload_completed"
2602 [(cond_exec
2603 (match_dup 4)
2604 (set (match_dup 0) (neg:SI (match_dup 2))))
2605 (cond_exec
2606 (match_dup 5)
2607 (set (match_dup 0) (match_dup 3)))]
2608 "
2609{
2610 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
2611 CCmode, operands[1], const0_rtx);
2612}")
2613
c65ebc55
JW
2614\f
2615;; ::::::::::::::::::::
2616;; ::
2617;; :: Call and branch instructions
2618;; ::
2619;; ::::::::::::::::::::
2620
2621;; Subroutine call instruction returning no value. Operand 0 is the function
2622;; to call; operand 1 is the number of bytes of arguments pushed (in mode
2623;; `SImode', except it is normally a `const_int'); operand 2 is the number of
2624;; registers used as operands.
2625
2626;; On most machines, operand 2 is not actually stored into the RTL pattern. It
2627;; is supplied for the sake of some RISC machines which need to put this
2628;; information into the assembler code; they can put it in the RTL instead of
2629;; operand 1.
2630
2631(define_expand "call"
2632 [(use (match_operand:DI 0 "" ""))
2633 (use (match_operand 1 "" ""))
2634 (use (match_operand 2 "" ""))
2635 (use (match_operand 3 "" ""))]
2636 ""
2637 "
2638{
2639 /* ??? Stripping off the MEM isn't correct. Will lose alias info. */
2640 rtx addr = XEXP (operands[0], 0);
2641 enum machine_mode mode = GET_MODE (addr);
2642
59da9a7d 2643 if (TARGET_NO_PIC || TARGET_AUTO_PIC)
c65ebc55
JW
2644 emit_call_insn (gen_call_internal (addr, operands[1],
2645 gen_rtx_REG (DImode, R_BR (0))));
2646
2647 /* If this is an indirect call, then we have the address of a descriptor. */
2648 else if (! symbolic_operand (addr, mode))
2649 emit_insn (gen_indirect_call_pic (addr, operands[1]));
59da9a7d
JW
2650 else if (TARGET_CONST_GP)
2651 emit_call_insn (gen_call_internal (addr, operands[1],
2652 gen_rtx_REG (DImode, R_BR (0))));
c65ebc55
JW
2653 /* ??? This is an unsatisfying solution. Should rethink. */
2654 else if (setjmp_operand (addr, mode))
2655 emit_insn (gen_setjmp_call_pic (addr, operands[1]));
2656 else
2657 emit_insn (gen_call_pic (addr, operands[1]));
2658
2659 DONE;
2660}")
2661
2662(define_expand "indirect_call_pic"
2663 [(set (match_dup 2) (reg:DI 1))
2664 (set (match_dup 3) (mem:DI (match_operand 0 "" "")))
2665 (set (match_dup 4) (plus:DI (match_dup 0) (const_int 8)))
2666 (set (reg:DI 1) (mem:DI (match_dup 4)))
2667 (parallel [(call (mem:DI (match_dup 3)) (match_operand 1 "" ""))
2668 (use (reg:DI 1))
2669 (clobber (reg:DI 320))])
2670 (set (reg:DI 1) (match_dup 2))]
2671 ""
2672 "
2673{
2674 operands[2] = gen_reg_rtx (DImode);
2675 operands[3] = gen_reg_rtx (DImode);
2676 operands[4] = gen_reg_rtx (DImode);
2677}")
2678
2679;; We can't save GP in a pseudo if we are calling setjmp, because pseudos
2680;; won't be restored by longjmp. For now, we save it in r4.
2681
2682;; ??? It would be more efficient to save this directly into a stack slot.
2683;; Unfortunately, the stack slot address gets cse'd across the setjmp call
2684;; because the NOTE_INSN_SETJMP note is in the wrong place.
2685
2686;; ??? This is an unsatisfying solution. Should rethink.
2687
2688(define_expand "setjmp_call_pic"
2689 [(set (match_dup 2) (reg:DI 1))
2690 (parallel [(call (mem:DI (match_operand 0 "" "")) (match_operand 1 "" ""))
2691 (use (reg:DI 1))
2692 (clobber (reg:DI 320))])
2693 (set (reg:DI 1) (match_dup 2))]
2694 ""
2695 "
2696{
2697 operands[2] = gen_rtx_REG (DImode, GR_REG (4));
2698}")
2699
2700;; ??? Saving/restoring the GP register is not needed if we are calling
2701;; a function in the same module.
2702
2703(define_expand "call_pic"
2704 [(set (match_dup 2) (reg:DI 1))
2705 (parallel [(call (mem:DI (match_operand 0 "" "")) (match_operand 1 "" ""))
2706 (use (reg:DI 1))
2707 (clobber (reg:DI 320))])
2708 (set (reg:DI 1) (match_dup 2))]
2709 ""
2710 "
2711{
2712 operands[2] = gen_reg_rtx (DImode);
2713}")
2714
c65ebc55
JW
2715(define_insn "call_internal"
2716 [(call (mem:DI (match_operand:DI 0 "call_operand" "bi"))
2717 (match_operand 1 "" ""))
2718 (clobber (match_operand:DI 2 "register_operand" "=b"))]
2719 ""
85548039 2720 "br.call%+.many %2 = %0"
c65ebc55
JW
2721 [(set_attr "type" "B")])
2722
2723(define_insn "*call_internal1"
2724 [(call (mem:DI (match_operand:DI 0 "call_operand" "bi"))
2725 (match_operand 1 "" ""))
2726 (use (reg:DI 1))
2727 (clobber (match_operand:DI 2 "register_operand" "=b"))]
2728 ""
85548039 2729 "br.call%+.many %2 = %0"
c65ebc55
JW
2730 [(set_attr "type" "B")])
2731
2732;; Subroutine call instruction returning a value. Operand 0 is the hard
2733;; register in which the value is returned. There are three more operands, the
2734;; same as the three operands of the `call' instruction (but with numbers
2735;; increased by one).
2736
2737;; Subroutines that return `BLKmode' objects use the `call' insn.
2738
2739(define_expand "call_value"
2740 [(use (match_operand 0 "" ""))
2741 (use (match_operand:DI 1 "" ""))
2742 (use (match_operand 2 "" ""))
2743 (use (match_operand 3 "" ""))
2744 (use (match_operand 4 "" ""))]
2745 ""
2746 "
2747{
2748 /* ??? Stripping off the MEM isn't correct. Will lose alias info. */
2749 rtx addr = XEXP (operands[1], 0);
2750 enum machine_mode mode = GET_MODE (addr);
2751
59da9a7d 2752 if (TARGET_NO_PIC || TARGET_AUTO_PIC)
c65ebc55
JW
2753 emit_call_insn (gen_call_value_internal (operands[0], addr, operands[2],
2754 gen_rtx_REG (DImode, R_BR (0))));
2755
2756 /* If this is an indirect call, then we have the address of a descriptor. */
2757 else if (! symbolic_operand (addr, mode))
2758 {
2759 /* This is for HFA returns. */
2760 if (GET_CODE (operands[0]) == PARALLEL)
2761 emit_insn (gen_indirect_call_multiple_values_pic (operands[0], addr,
2762 operands[2]));
2763 else
2764 emit_insn (gen_indirect_call_value_pic (operands[0], addr,
2765 operands[2]));
2766 }
59da9a7d
JW
2767 else if (TARGET_CONST_GP)
2768 emit_call_insn (gen_call_value_internal (operands[0], addr, operands[2],
2769 gen_rtx_REG (DImode, R_BR (0))));
c65ebc55
JW
2770 /* ??? This is an unsatisfying solution. Should rethink. */
2771 else if (setjmp_operand (addr, mode))
2772 emit_insn (gen_setjmp_call_value_pic (operands[0], addr, operands[2]));
2773 /* This is for HFA returns. */
2774 else if (GET_CODE (operands[0]) == PARALLEL)
2775 emit_insn (gen_call_multiple_values_pic (operands[0], addr, operands[2]));
2776 else
2777 emit_insn (gen_call_value_pic (operands[0], addr, operands[2]));
2778
2779 DONE;
2780}")
2781
2782(define_expand "indirect_call_value_pic"
2783 [(set (match_dup 3) (reg:DI 1))
2784 (set (match_dup 4) (mem:DI (match_operand 1 "" "")))
2785 (set (match_dup 5) (plus:DI (match_dup 1) (const_int 8)))
2786 (set (reg:DI 1) (mem:DI (match_dup 5)))
2787 (parallel [(set (match_operand 0 "" "")
2788 (call (mem:DI (match_dup 4)) (match_operand 2 "" "")))
2789 (use (reg:DI 1))
2790 (clobber (reg:DI 320))])
2791 (set (reg:DI 1) (match_dup 3))]
2792 ""
2793 "
2794{
2795 operands[3] = gen_reg_rtx (DImode);
2796 operands[4] = gen_reg_rtx (DImode);
2797 operands[5] = gen_reg_rtx (DImode);
2798}")
2799
2800(define_expand "indirect_call_multiple_values_pic"
2801 [(set (match_dup 3) (reg:DI 1))
2802 (set (match_dup 4) (mem:DI (match_operand 1 "" "")))
2803 (set (match_dup 5) (plus:DI (match_dup 1) (const_int 8)))
2804 (set (reg:DI 1) (mem:DI (match_dup 5)))
2805 (match_par_dup 6 [(set (match_operand 0 "" "")
2806 (call (mem:DI (match_dup 4))
2807 (match_operand 2 "" "")))
2808 (use (reg:DI 1))
2809 (clobber (reg:DI 320))])
2810 (set (reg:DI 1) (match_dup 3))]
2811 ""
2812 "
2813{
2814 int count;
2815 int i;
2816 rtx call;
2817
2818 operands[3] = gen_reg_rtx (DImode);
2819 operands[4] = gen_reg_rtx (DImode);
2820 operands[5] = gen_reg_rtx (DImode);
2821
2822 /* This code is the same as the code in call_multiple_values_pic, except
2823 that op3 was replaced with op6 and op1 was replaced with op4. */
2824 call = gen_rtx_CALL (VOIDmode, gen_rtx_MEM (DImode, operands[4]),
2825 operands[2]);
2826
2827 count = XVECLEN (operands[0], 0);
2828 operands[6] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 2));
2829
2830 XVECEXP (operands[6], 0, 0)
2831 = gen_rtx_SET (VOIDmode, XEXP (XVECEXP (operands[0], 0, 0), 0), call);
2832
2833 XVECEXP (operands[6], 0, 1)
2834 = gen_rtx_USE (DImode, gen_rtx_REG (DImode, GR_REG (1)));
2835 XVECEXP (operands[6], 0, 2)
2836 = gen_rtx_CLOBBER (DImode, gen_rtx_REG (DImode, BR_REG (0)));
2837
2838 for (i = 1; i < count; i++)
2839 XVECEXP (operands[6], 0, i + 2)
2840 = gen_rtx_SET (VOIDmode, XEXP (XVECEXP (operands[0], 0, i), 0), call);
2841
2842}")
2843
2844;; We can't save GP in a pseudo if we are calling setjmp, because pseudos
2845;; won't be restored by longjmp. For now, we save it in r4.
2846
2847;; ??? It would be more efficient to save this directly into a stack slot.
2848;; Unfortunately, the stack slot address gets cse'd across the setjmp call
2849;; because the NOTE_INSN_SETJMP note is in the wrong place.
2850
2851;; ??? This is an unsatisfying solution. Should rethink.
2852
2853(define_expand "setjmp_call_value_pic"
2854 [(set (match_dup 3) (reg:DI 1))
2855 (parallel [(set (match_operand 0 "" "")
2856 (call (mem:DI (match_operand 1 "" ""))
2857 (match_operand 2 "" "")))
2858 (use (reg:DI 1))
2859 (clobber (reg:DI 320))])
2860 (set (reg:DI 1) (match_dup 3))]
2861 ""
2862 "
2863{
2864 operands[3] = gen_rtx_REG (DImode, GR_REG (4));
2865}")
2866
2867;; ??? Saving/restoring the GP register is not needed if we are calling
2868;; a function in the same module.
2869
2870(define_expand "call_value_pic"
2871 [(set (match_dup 3) (reg:DI 1))
2872 (parallel [(set (match_operand 0 "" "")
2873 (call (mem:DI (match_operand 1 "" ""))
2874 (match_operand 2 "" "")))
2875 (use (reg:DI 1))
2876 (clobber (reg:DI 320))])
2877 (set (reg:DI 1) (match_dup 3))]
2878 ""
2879 "
2880{
2881 operands[3] = gen_reg_rtx (DImode);
2882}")
2883
2884;; ??? Saving/restoring the GP register is not needed if we are calling
2885;; a function in the same module.
2886
2887(define_expand "call_multiple_values_pic"
2888 [(set (match_dup 4) (reg:DI 1))
2889 (match_par_dup 3 [(set (match_operand 0 "" "")
2890 (call (mem:DI (match_operand 1 "" ""))
2891 (match_operand 2 "" "")))
2892 (use (reg:DI 1))
2893 (clobber (reg:DI 320))])
2894 (set (reg:DI 1) (match_dup 4))]
2895 ""
2896 "
2897{
2898 int count;
2899 int i;
2900 rtx call;
2901
2902 operands[4] = gen_reg_rtx (DImode);
2903
2904 call = gen_rtx_CALL (VOIDmode, gen_rtx_MEM (DImode, operands[1]),
2905 operands[2]);
2906
2907 count = XVECLEN (operands[0], 0);
2908 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 2));
2909
2910 XVECEXP (operands[3], 0, 0)
2911 = gen_rtx_SET (VOIDmode, XEXP (XVECEXP (operands[0], 0, 0), 0), call);
2912
2913 XVECEXP (operands[3], 0, 1)
2914 = gen_rtx_USE (DImode, gen_rtx_REG (DImode, GR_REG (1)));
2915 XVECEXP (operands[3], 0, 2)
2916 = gen_rtx_CLOBBER (DImode, gen_rtx_REG (DImode, BR_REG (0)));
2917
2918 for (i = 1; i < count; i++)
2919 XVECEXP (operands[3], 0, i + 2)
2920 = gen_rtx_SET (VOIDmode, XEXP (XVECEXP (operands[0], 0, i), 0), call);
2921}")
2922
c65ebc55
JW
2923(define_insn "call_value_internal"
2924 [(set (match_operand 0 "register_operand" "=rf")
2925 (call (mem:DI (match_operand:DI 1 "call_operand" "bi"))
2926 (match_operand 2 "" "")))
2927 (clobber (match_operand:DI 3 "register_operand" "=b"))]
2928 ""
85548039 2929 "br.call%+.many %3 = %1"
c65ebc55
JW
2930 [(set_attr "type" "B")])
2931
2932(define_insn "*call_value_internal1"
2933 [(set (match_operand 0 "register_operand" "=rf")
2934 (call (mem:DI (match_operand:DI 1 "call_operand" "bi"))
2935 (match_operand 2 "" "")))
2936 (use (reg:DI 1))
2937 (clobber (match_operand:DI 3 "register_operand" "=b"))]
2938 ""
85548039 2939 "br.call%+.many %3 = %1"
c65ebc55
JW
2940 [(set_attr "type" "B")])
2941
2942(define_insn "*call_multiple_values_internal1"
2943 [(match_parallel 0 "call_multiple_values_operation"
2944 [(set (match_operand 1 "register_operand" "=rf")
2945 (call (mem:DI (match_operand:DI 2 "call_operand" "bi"))
2946 (match_operand 3 "" "")))
2947 (use (reg:DI 1))
2948 (clobber (match_operand:DI 4 "register_operand" "=b"))])]
2949 ""
85548039 2950 "br.call%+.many %4 = %2"
c65ebc55
JW
2951 [(set_attr "type" "B")])
2952
2953;; Call subroutine returning any type.
2954
2955(define_expand "untyped_call"
2956 [(parallel [(call (match_operand 0 "" "")
2957 (const_int 0))
2958 (match_operand 1 "" "")
2959 (match_operand 2 "" "")])]
2960 ""
2961 "
2962{
2963 int i;
2964
2965 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
2966
2967 for (i = 0; i < XVECLEN (operands[2], 0); i++)
2968 {
2969 rtx set = XVECEXP (operands[2], 0, i);
2970 emit_move_insn (SET_DEST (set), SET_SRC (set));
2971 }
2972
2973 /* The optimizer does not know that the call sets the function value
2974 registers we stored in the result block. We avoid problems by
2975 claiming that all hard registers are used and clobbered at this
2976 point. */
2977 emit_insn (gen_blockage ());
2978
2979 DONE;
2980}")
2981
2982(define_insn "return_internal"
2983 [(return)
2984 (use (match_operand:DI 0 "register_operand" "b"))]
2985 ""
2986 "br.ret.sptk.many %0"
2987 [(set_attr "type" "B")])
2988
2989(define_insn "return"
2990 [(return)]
2991 "ia64_direct_return ()"
2992 "br.ret.sptk.many rp"
2993 [(set_attr "type" "B")])
2994
6b6c1201 2995(define_insn "*return_true"
c65ebc55 2996 [(set (pc)
6b6c1201
RH
2997 (if_then_else (match_operator 0 "predicate_operator"
2998 [(match_operand:CC 1 "register_operand" "c")
2999 (const_int 0)])
c65ebc55
JW
3000 (return)
3001 (pc)))]
3002 "ia64_direct_return ()"
85548039 3003 "(%%J0) br.ret%+.many rp"
e5bde68a
RH
3004 [(set_attr "type" "B")
3005 (set_attr "predicable" "no")])
c65ebc55 3006
6b6c1201 3007(define_insn "*return_false"
c65ebc55 3008 [(set (pc)
6b6c1201
RH
3009 (if_then_else (match_operator 0 "predicate_operator"
3010 [(match_operand:CC 1 "register_operand" "c")
3011 (const_int 0)])
c65ebc55
JW
3012 (pc)
3013 (return)))]
3014 "ia64_direct_return ()"
85548039 3015 "(%%j0) br.ret%+.many rp"
e5bde68a
RH
3016 [(set_attr "type" "B")
3017 (set_attr "predicable" "no")])
c65ebc55
JW
3018
3019(define_insn "jump"
3020 [(set (pc) (label_ref (match_operand 0 "" "")))]
3021 ""
3022 "br %l0"
3023 [(set_attr "type" "B")])
3024
3025(define_insn "indirect_jump"
3026 [(set (pc) (match_operand:DI 0 "register_operand" "b"))]
3027 ""
3028 "br %0"
3029 [(set_attr "type" "B")])
3030
3031(define_expand "tablejump"
3032 [(match_operand:DI 0 "register_operand" "")
3033 (match_operand 1 "" "")]
3034 ""
3035 "
3036{
3037 rtx tmp1 = gen_reg_rtx (DImode);
3038 rtx tmp2 = gen_reg_rtx (DImode);
3039
3040 emit_move_insn (tmp1, gen_rtx_LABEL_REF (Pmode, operands[1]));
3041 emit_insn (gen_adddi3 (tmp2, operands[0], tmp1));
3042 emit_jump_insn (gen_tablejump_internal (tmp2, operands[1]));
3043 DONE;
3044}")
3045
3046(define_insn "tablejump_internal"
3047 [(set (pc) (match_operand:DI 0 "register_operand" "b"))
3048 (use (label_ref (match_operand 1 "" "")))]
3049 ""
3050 "br %0"
3051 [(set_attr "type" "B")])
3052
3053\f
3054;; ::::::::::::::::::::
3055;; ::
3056;; :: Prologue and Epilogue instructions
3057;; ::
3058;; ::::::::::::::::::::
3059
3060(define_expand "prologue"
3061 [(const_int 1)]
3062 ""
3063 "
3064{
3065 ia64_expand_prologue ();
3066 DONE;
3067}")
3068
3069(define_expand "epilogue"
3070 [(const_int 2)]
3071 ""
3072 "
3073{
3074 ia64_expand_epilogue ();
3075 DONE;
3076}")
3077
3078;; This prevents the scheduler from moving the SP decrement past FP-relative
3079;; stack accesses. This is the same as adddi3 plus the extra set.
3080
3081(define_insn "prologue_allocate_stack"
3082 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
3083 (plus:DI (match_operand:DI 1 "register_operand" "%r,r,a")
3084 (match_operand:DI 2 "reg_or_22bit_operand" "r,I,J")))
3085 (set (match_operand:DI 3 "register_operand" "=r,r,r")
3086 (match_dup 3))]
3087 ""
3088 "@
3089 add %0 = %1, %2
3090 adds %0 = %2, %1
3091 addl %0 = %2, %1"
3092 [(set_attr "type" "A")])
3093
3094;; This prevents the scheduler from moving the SP restore past FP-relative
3095;; stack accesses. This is similar to movdi plus the extra set.
3096
3097(define_insn "epilogue_deallocate_stack"
3098 [(set (match_operand:DI 0 "register_operand" "=r")
3099 (match_operand:DI 1 "register_operand" "+r"))
3100 (set (match_dup 1) (match_dup 1))]
3101 ""
3102 "mov %0 = %1"
3103 [(set_attr "type" "A")])
3104
3105;; Allocate a new register frame.
3106
3107(define_insn "alloc"
3108 [(set (match_operand:DI 0 "register_operand" "=r")
3109 (unspec_volatile:DI [(const_int 0)] 0))
3110 (use (match_operand:DI 1 "const_int_operand" "i"))
3111 (use (match_operand:DI 2 "const_int_operand" "i"))
3112 (use (match_operand:DI 3 "const_int_operand" "i"))
3113 (use (match_operand:DI 4 "const_int_operand" "i"))]
3114 ""
3115 "alloc %0 = ar.pfs, %1, %2, %3, %4"
e5bde68a
RH
3116 [(set_attr "type" "M")
3117 (set_attr "predicable" "no")])
c65ebc55
JW
3118
3119(define_insn "gr_spill"
3120 [(set (match_operand:DI 0 "memory_operand" "=m")
3121 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] 1))]
3122 ""
3123 "st8.spill %0 = %1%P0"
3124 [(set_attr "type" "M")])
3125
3126(define_insn "gr_restore"
3127 [(set (match_operand:DI 0 "register_operand" "=r")
3128 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] 2))]
3129 ""
3130 "ld8.fill %0 = %1%P1"
3131 [(set_attr "type" "M")])
3132
3133(define_insn "fr_spill"
3134 [(set (match_operand:XF 0 "memory_operand" "=m")
3135 (unspec:XF [(match_operand:XF 1 "register_operand" "f*e")] 3))]
3136 ""
3137 "stf.spill %0 = %1%P0"
3138 [(set_attr "type" "M")])
3139
3140(define_insn "fr_restore"
3141 [(set (match_operand:XF 0 "register_operand" "=f*e")
3142 (unspec:XF [(match_operand:XF 1 "memory_operand" "m")] 4))]
3143 ""
3144 "ldf.fill %0 = %1%P1"
3145 [(set_attr "type" "M")])
3146
3147(define_insn "pr_spill"
3148 [(set (match_operand:DI 0 "register_operand" "=r")
3149 (unspec:DI [(const_int 0)] 5))]
3150 ""
3151 "mov %0 = pr"
3152 [(set_attr "type" "I")])
3153
d4daa0b4
JW
3154;; ??? This is volatile to prevent it from being moved before a conditional
3155;; expression that calculates the return value.
3156
c65ebc55 3157(define_insn "pr_restore"
d4daa0b4 3158 [(unspec_volatile [(const_int 0)] 6)
c65ebc55
JW
3159 (use (match_operand:DI 0 "register_operand" "r"))]
3160 ""
3161 "mov pr = %0, -1"
3162 [(set_attr "type" "I")])
3163
3164;; ??? This is volatile to prevent it from being moved before a call.
3165;; Should instead add a ar.pfs hard register which is call clobbered.
3166
3167(define_insn "pfs_restore"
3168 [(unspec_volatile [(const_int 0)] 4)
3169 (use (match_operand:DI 0 "register_operand" "r"))]
3170 ""
3171 "mov ar.pfs = %0"
3172 [(set_attr "type" "I")])
3173
3174(define_insn "unat_spill"
3175 [(set (match_operand:DI 0 "register_operand" "=r")
3176 (unspec:DI [(const_int 0)] 9))]
3177 ""
3178 "mov %0 = ar.unat"
3179 [(set_attr "type" "M")])
3180
3181(define_insn "unat_restore"
3182 [(unspec [(const_int 0)] 10)
3183 (use (match_operand:DI 0 "register_operand" "r"))]
3184 ""
3185 "mov ar.unat = %0"
3186 [(set_attr "type" "M")])
3187
0c96007e
AM
3188(define_insn "bsp_value"
3189 [(set (match_operand:DI 0 "register_operand" "=r")
3190 (unspec:DI [(const_int 0)] 20))]
3191 ""
3192 "mov %0 = ar.bsp"
3193 [(set_attr "type" "I")])
3194
3195(define_insn "set_bsp"
3196 [(unspec_volatile [(const_int 0)] 5)
3197 (use (match_operand:DI 0 "register_operand" "r"))]
3198 ""
3199 "flushrs\; \
3200 mov r19=ar.rsc\; \
3201 ;;\; \
3202 and r19=0x1c,r19\; \
3203 ;;\; \
3204 mov ar.rsc=r19\; \
3205 ;;\; \
3206 mov ar.bspstore=%0\; \
3207 ;;\; \
3208 or r19=0x3,r19\; \
3209 ;;\; \
3210 loadrs\; \
3211 invala\; \
3212 ;;\; \
3213 mov ar.rsc=r19\;"
e5bde68a
RH
3214 [(set_attr "type" "unknown")
3215 (set_attr "predicable" "no")])
ce152ef8
AM
3216
3217(define_insn "flushrs"
3218 [(unspec [(const_int 0)] 21)]
3219 ""
3220 ";; \; flushrs"
3221 [(set_attr "type" "M")])
c65ebc55
JW
3222\f
3223;; ::::::::::::::::::::
3224;; ::
3225;; :: Miscellaneous instructions
3226;; ::
3227;; ::::::::::::::::::::
3228
3229;; ??? Emiting a NOP instruction isn't very useful. This should probably
3230;; be emitting ";;" to force a break in the instruction packing.
3231
3232;; No operation, needed in case the user uses -g but not -O.
3233(define_insn "nop"
3234 [(const_int 0)]
3235 ""
3236 "nop 0"
3237 [(set_attr "type" "unknown")])
3238
3239;; Pseudo instruction that prevents the scheduler from moving code above this
3240;; point.
3241(define_insn "blockage"
3242 [(unspec_volatile [(const_int 0)] 1)]
3243 ""
3244 ""
e5bde68a
RH
3245 [(set_attr "type" "unknown")
3246 (set_attr "predicable" "no")])
c65ebc55
JW
3247
3248(define_insn "insn_group_barrier"
3249 [(unspec_volatile [(const_int 0)] 2)]
3250 ""
3251 ";;"
e5bde68a
RH
3252 [(set_attr "type" "S")
3253 (set_attr "predicable" "no")])
c65ebc55
JW
3254
3255\f
3256;; Non-local goto support.
3257
3258(define_expand "save_stack_nonlocal"
3259 [(use (match_operand:OI 0 "memory_operand" ""))
3260 (use (match_operand:DI 1 "register_operand" ""))]
3261 ""
3262 "
3263{
3264 emit_library_call (gen_rtx_SYMBOL_REF (Pmode,
3265 \"__ia64_save_stack_nonlocal\"),
3266 0, VOIDmode, 2, XEXP (operands[0], 0), Pmode,
3267 operands[1], Pmode);
3268 DONE;
3269}")
3270
3271(define_expand "nonlocal_goto"
3272 [(use (match_operand 0 "general_operand" ""))
3273 (use (match_operand 1 "general_operand" ""))
3274 (use (match_operand 2 "general_operand" ""))
3275 (use (match_operand 3 "general_operand" ""))]
3276 ""
3277 "
3278{
3279 if (GET_CODE (operands[0]) != REG)
3280 operands[0] = force_reg (Pmode, operands[0]);
3281 emit_move_insn (virtual_stack_vars_rtx, operands[0]);
3282 emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));
3283 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3284 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
3285 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, \"__ia64_nonlocal_goto\"),
3286 0, VOIDmode, 4,
3287 operands[0], Pmode, operands[1], Pmode,
3288 copy_to_reg (XEXP (operands[2], 0)), Pmode,
3289 operands[3], Pmode);
3290 emit_barrier ();
3291 DONE;
3292}")
3293
3294;; ??? We need this because the function __ia64_nonlocal_goto can't easily
3295;; access the FP which is currently stored in a local register. Maybe move
3296;; the FP to a global register to avoid this problem?
3297
3298(define_expand "nonlocal_goto_receiver"
3299 [(use (const_int 0))]
3300 ""
3301 "
3302{
3303 emit_move_insn (frame_pointer_rtx, gen_rtx_REG (DImode, GR_REG (7)));
3304 DONE;
3305}")
3306
0c96007e
AM
3307(define_expand "eh_epilogue"
3308 [(use (match_operand:DI 0 "register_operand" "r"))
3309 (use (match_operand:DI 1 "register_operand" "r"))
3310 (use (match_operand:DI 2 "register_operand" "r"))]
3311 ""
3312 "
3313{
3314 rtx bsp = gen_rtx_REG (Pmode, 10);
3315 rtx sp = gen_rtx_REG (Pmode, 9);
3316
3317 if (GET_CODE (operands[0]) != REG || REGNO (operands[0]) != 10)
3318 {
3319 emit_move_insn (bsp, operands[0]);
3320 operands[0] = bsp;
3321 }
3322 if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 9)
3323 {
3324 emit_move_insn (sp, operands[2]);
3325 operands[2] = sp;
3326 }
3327 emit_insn (gen_rtx_USE (VOIDmode, sp));
3328 emit_insn (gen_rtx_USE (VOIDmode, bsp));
3329
3330 cfun->machine->ia64_eh_epilogue_sp = sp;
3331 cfun->machine->ia64_eh_epilogue_bsp = bsp;
3332
3333}")
3334
c65ebc55
JW
3335;; This flushes at least 64 bytes starting from the address pointed
3336;; to by operand[0].
3337
3338;; ??? This should be a define expand.
3339
3340(define_insn "flush_cache"
3341 [(unspec_volatile [(match_operand:DI 0 "register_operand" "=&r")] 3)]
3342 ""
3343 "fc %0\;;;\;adds %0=31,%0\;;;\;fc %0\;;;\;sync.i\;srlz.i"
e5bde68a
RH
3344 [(set_attr "type" "unknown")
3345 (set_attr "predicable" "no")])
9525c690
JW
3346\f
3347;; Builtin apply support.
3348
3349(define_expand "restore_stack_nonlocal"
3350 [(use (match_operand:DI 0 "register_operand" ""))
3351 (use (match_operand:OI 1 "memory_operand" ""))]
3352 ""
3353 "
3354{
3355 emit_library_call (gen_rtx_SYMBOL_REF (Pmode,
3356 \"__ia64_restore_stack_nonlocal\"),
3357 0, VOIDmode, 1,
3358 copy_to_reg (XEXP (operands[1], 0)), Pmode);
3359 DONE;
3360}")
3361
3362\f
3363;;; Intrinsics support.
c65ebc55
JW
3364
3365(define_insn "ccv_restore_si"
3366 [(unspec [(const_int 0)] 11)
3367 (use (match_operand:SI 0 "register_operand" "r"))]
3368 ""
3369 "mov ar.ccv = %0"
3370 [(set_attr "type" "M")])
3371
3372(define_insn "ccv_restore_di"
3373 [(unspec [(const_int 0)] 11)
3374 (use (match_operand:DI 0 "register_operand" "r"))]
3375 ""
3376 "mov ar.ccv = %0"
3377 [(set_attr "type" "M")])
3378
3379(define_insn "mf"
3380 [(unspec [(match_operand:BLK 0 "memory_operand" "m")] 12)]
3381 ""
3382 "mf"
3383 [(set_attr "type" "M")])
3384
3385(define_insn "fetchadd_acq_si"
3386 [(set (match_operand:SI 0 "register_operand" "=r")
3387 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
3388 (match_operand:SI 2 "fetchadd_operand" "n")] 19))]
3389 ""
3390 "fetchadd4.acq %0 = %1, %2"
3391 [(set_attr "type" "M")])
3392
3393(define_insn "fetchadd_acq_di"
3394 [(set (match_operand:DI 0 "register_operand" "=r")
3395 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
3396 (match_operand:DI 2 "fetchadd_operand" "n")] 19))]
3397 ""
3398 "fetchadd8.acq %0 = %1, %2"
3399 [(set_attr "type" "M")])
3400
3401(define_insn "cmpxchg_acq_si"
3402 [(set (match_operand:SI 0 "register_operand" "=r")
3403 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
3404 (match_operand:SI 2 "register_operand" "r")] 13))]
3405 ""
3406 "cmpxchg4.acq %0 = %1, %2, ar.ccv"
3407 [(set_attr "type" "M")])
3408
3409(define_insn "cmpxchg_acq_di"
3410 [(set (match_operand:DI 0 "register_operand" "=r")
3411 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
3412 (match_operand:DI 2 "register_operand" "r")] 13))]
3413 ""
3414 "cmpxchg8.acq %0 = %1, %2, ar.ccv"
3415 [(set_attr "type" "M")])
3416
3417(define_expand "val_compare_and_swap_si"
3418 [(set (match_operand:SI 0 "register_operand" "=r")
3419 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
3420 (match_operand:SI 2 "register_operand" "r")
3421 (match_operand:SI 3 "register_operand" "r")] 14))]
3422 ""
3423 "
3424{
3425 rtx tmp_reg = gen_rtx_REG (DImode, GR_REG(0));
3426 rtx target = gen_rtx_MEM (BLKmode, tmp_reg);
3427 RTX_UNCHANGING_P (target) = 1;
3428 emit_insn (gen_ccv_restore_si (operands[2]));
3429 emit_insn (gen_mf (target));
3430 emit_insn (gen_cmpxchg_acq_si (operands[0], operands[1], operands[3]));
3431 DONE;
3432}")
3433
3434(define_expand "val_compare_and_swap_di"
3435 [(set (match_operand:DI 0 "register_operand" "=r")
3436 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
3437 (match_operand:DI 2 "register_operand" "r")
3438 (match_operand:DI 3 "register_operand" "r")] 14))]
3439 ""
3440 "
3441{
3442 rtx tmp_reg = gen_rtx_REG (DImode, GR_REG(0));
3443 rtx target = gen_rtx_MEM (BLKmode, tmp_reg);
3444 RTX_UNCHANGING_P (target) = 1;
3445 emit_insn (gen_ccv_restore_di (operands[2]));
3446 emit_insn (gen_mf (target));
3447 emit_insn (gen_cmpxchg_acq_di (operands[0], operands[1], operands[3]));
3448 DONE;
3449}")
3450
3451(define_insn "xchgsi"
3452 [(set (match_operand:SI 0 "register_operand" "=r")
3453 (match_operand:SI 1 "memory_operand" "+m"))
3454 (set (match_dup 1)
3455 (match_operand:SI 2 "register_operand" "r"))]
3456 ""
3457 "xchg4 %0 = %1, %2"
3458 [(set_attr "type" "M")])
3459
3460(define_insn "xchgdi"
3461 [(set (match_operand:DI 0 "register_operand" "=r")
3462 (match_operand:DI 1 "memory_operand" "+m"))
3463 (set (match_dup 1)
3464 (match_operand:DI 2 "register_operand" "r"))]
3465 ""
3466 "xchg8 %0 = %1, %2"
3467 [(set_attr "type" "M")])
3468
3469(define_expand "lock_test_and_set_si"
3470 [(set (match_operand:SI 0 "register_operand" "r")
3471 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
3472 (match_operand:SI 2 "register_operand" "r")] 16))]
3473 ""
3474 "
3475{
3476 emit_insn (gen_xchgsi (operands[0], operands[1], operands[2]));
3477 DONE;
3478}")
3479
3480(define_expand "lock_test_and_set_di"
3481 [(set (match_operand:DI 0 "register_operand" "r")
3482 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
3483 (match_operand:DI 2 "register_operand" "r")] 16))]
3484 ""
3485 "
3486{
3487 emit_insn (gen_xchgdi (operands[0], operands[1], operands[2]));
3488 DONE;
3489}")
3490
3491(define_expand "fetch_and_add_si"
3492 [(set (match_operand:SI 0 "register_operand" "r")
3493 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
3494 (match_operand:SI 2 "nonmemory_operand" "")] 18))]
3495 ""
3496 "
3497{
3498 int x;
3499
3500 if (GET_CODE (operands[2]) == CONST_INT)
3501 {
3502 x = INTVAL(operands[2]);
3503 if (x == -16 || x == -8 || x == -4 || x == -1 ||
3504 x == 16 || x == 8 || x == 4 || x == 1)
3505 {
3506 emit_insn (gen_fetchadd_acq_si (operands[0], operands[1], operands[2]));
3507 DONE;
3508 }
3509 }
3510
3511 ia64_expand_fetch_and_op (IA64_ADD_OP, SImode, operands);
3512 DONE;
3513}")
3514
3515(define_expand "fetch_and_sub_si"
3516 [(set (match_operand:SI 0 "register_operand" "r")
3517 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
3518 (match_operand:SI 2 "register_operand" "r")] 18))]
3519 ""
3520 "
3521{
3522 ia64_expand_fetch_and_op (IA64_SUB_OP, SImode, operands);
3523 DONE;
3524}")
3525
3526(define_expand "fetch_and_or_si"
3527 [(set (match_operand:SI 0 "register_operand" "r")
3528 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
3529 (match_operand:SI 2 "register_operand" "r")] 18))]
3530 ""
3531 "
3532{
3533 ia64_expand_fetch_and_op (IA64_OR_OP, SImode, operands);
3534 DONE;
3535}")
3536
3537(define_expand "fetch_and_and_si"
3538 [(set (match_operand:SI 0 "register_operand" "r")
3539 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
3540 (match_operand:SI 2 "register_operand" "r")] 18))]
3541 ""
3542 "
3543{
3544 ia64_expand_fetch_and_op (IA64_AND_OP, SImode, operands);
3545 DONE;
3546}")
3547
3548(define_expand "fetch_and_xor_si"
3549 [(set (match_operand:SI 0 "register_operand" "r")
3550 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
3551 (match_operand:SI 2 "register_operand" "r")] 18))]
3552 ""
3553 "
3554{
3555 ia64_expand_fetch_and_op (IA64_XOR_OP, SImode, operands);
3556 DONE;
3557}")
3558
3559(define_expand "fetch_and_nand_si"
3560 [(set (match_operand:SI 0 "register_operand" "r")
3561 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
3562 (match_operand:SI 2 "register_operand" "r")] 18))]
3563 ""
3564 "
3565{
3566 ia64_expand_fetch_and_op (IA64_NAND_OP, SImode, operands);
3567 DONE;
3568}")
3569
3570(define_expand "fetch_and_add_di"
3571 [(set (match_operand:DI 0 "register_operand" "r")
3572 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
3573 (match_operand:DI 2 "nonmemory_operand" "")] 18))]
3574 ""
3575 "
3576{
3577 int x;
3578
3579 if (GET_CODE (operands[2]) == CONST_INT)
3580 {
3581 x = INTVAL(operands[2]);
3582 if (x == -16 || x == -8 || x == -4 || x == -1 ||
3583 x == 16 || x == 8 || x == 4 || x == 1)
3584 {
3585 emit_insn (gen_fetchadd_acq_di (operands[0], operands[1], operands[2]));
3586 DONE;
3587 }
3588 }
3589
3590 ia64_expand_fetch_and_op (IA64_ADD_OP, DImode, operands);
3591 DONE;
3592}")
3593
3594(define_expand "fetch_and_sub_di"
3595 [(set (match_operand:DI 0 "register_operand" "r")
3596 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
3597 (match_operand:DI 2 "register_operand" "r")] 18))]
3598 ""
3599 "
3600{
3601 ia64_expand_fetch_and_op (IA64_SUB_OP, DImode, operands);
3602 DONE;
3603}")
3604
3605(define_expand "fetch_and_or_di"
3606 [(set (match_operand:DI 0 "register_operand" "r")
3607 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
3608 (match_operand:DI 2 "register_operand" "r")] 18))]
3609 ""
3610 "
3611{
3612 ia64_expand_fetch_and_op (IA64_OR_OP, DImode, operands);
3613 DONE;
3614}")
3615
3616(define_expand "fetch_and_and_di"
3617 [(set (match_operand:DI 0 "register_operand" "r")
3618 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
3619 (match_operand:DI 2 "register_operand" "r")] 18))]
3620 ""
3621 "
3622{
3623 ia64_expand_fetch_and_op (IA64_AND_OP, DImode, operands);
3624 DONE;
3625}")
3626
3627(define_expand "fetch_and_xor_di"
3628 [(set (match_operand:DI 0 "register_operand" "r")
3629 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
3630 (match_operand:DI 2 "register_operand" "r")] 18))]
3631 ""
3632 "
3633{
3634 ia64_expand_fetch_and_op (IA64_XOR_OP, DImode, operands);
3635 DONE;
3636}")
3637
3638(define_expand "fetch_and_nand_di"
3639 [(set (match_operand:DI 0 "register_operand" "r")
3640 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
3641 (match_operand:DI 2 "register_operand" "r")] 18))]
3642 ""
3643 "
3644{
3645 ia64_expand_fetch_and_op (IA64_NAND_OP, DImode, operands);
3646 DONE;
3647}")
3648
3649(define_expand "add_and_fetch_di"
3650 [(set (match_operand:DI 0 "register_operand" "r")
3651 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
3652 (match_operand:DI 2 "register_operand" "r")] 17))]
3653 ""
3654 "
3655{
3656 ia64_expand_op_and_fetch (IA64_ADD_OP, DImode, operands);
3657 DONE;
3658}")
3659
3660(define_expand "sub_and_fetch_di"
3661 [(set (match_operand:DI 0 "register_operand" "r")
3662 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
3663 (match_operand:DI 2 "register_operand" "r")] 17))]
3664 ""
3665 "
3666{
3667 ia64_expand_op_and_fetch (IA64_SUB_OP, DImode, operands);
3668 DONE;
3669}")
3670
3671(define_expand "or_and_fetch_di"
3672 [(set (match_operand:DI 0 "register_operand" "r")
3673 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
3674 (match_operand:DI 2 "register_operand" "r")] 17))]
3675 ""
3676 "
3677{
3678 ia64_expand_op_and_fetch (IA64_OR_OP, DImode, operands);
3679 DONE;
3680}")
3681
3682(define_expand "and_and_fetch_di"
3683 [(set (match_operand:DI 0 "register_operand" "r")
3684 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
3685 (match_operand:DI 2 "register_operand" "r")] 17))]
3686 ""
3687 "
3688{
3689 ia64_expand_op_and_fetch (IA64_AND_OP, DImode, operands);
3690 DONE;
3691}")
3692
3693(define_expand "xor_and_fetch_di"
3694 [(set (match_operand:DI 0 "register_operand" "r")
3695 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
3696 (match_operand:DI 2 "register_operand" "r")] 17))]
3697 ""
3698 "
3699{
3700 ia64_expand_op_and_fetch (IA64_XOR_OP, DImode, operands);
3701 DONE;
3702}")
3703
3704(define_expand "nand_and_fetch_di"
3705 [(set (match_operand:DI 0 "register_operand" "r")
3706 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
3707 (match_operand:DI 2 "register_operand" "r")] 17))]
3708 ""
3709 "
3710{
3711 ia64_expand_op_and_fetch (IA64_NAND_OP, DImode, operands);
3712 DONE;
3713}")
3714
3715(define_expand "add_and_fetch_si"
3716 [(set (match_operand:SI 0 "register_operand" "r")
3717 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
3718 (match_operand:SI 2 "register_operand" "r")] 17))]
3719 ""
3720 "
3721{
3722 ia64_expand_op_and_fetch (IA64_ADD_OP, SImode, operands);
3723 DONE;
3724}")
3725
3726(define_expand "sub_and_fetch_si"
3727 [(set (match_operand:SI 0 "register_operand" "r")
3728 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
3729 (match_operand:SI 2 "register_operand" "r")] 17))]
3730 ""
3731 "
3732{
3733 ia64_expand_op_and_fetch (IA64_SUB_OP, SImode, operands);
3734 DONE;
3735}")
3736
3737(define_expand "or_and_fetch_si"
3738 [(set (match_operand:SI 0 "register_operand" "r")
3739 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
3740 (match_operand:SI 2 "register_operand" "r")] 17))]
3741 ""
3742 "
3743{
3744 ia64_expand_op_and_fetch (IA64_OR_OP, SImode, operands);
3745 DONE;
3746}")
3747
3748(define_expand "and_and_fetch_si"
3749 [(set (match_operand:SI 0 "register_operand" "r")
3750 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
3751 (match_operand:SI 2 "register_operand" "r")] 17))]
3752 ""
3753 "
3754{
3755 ia64_expand_op_and_fetch (IA64_AND_OP, SImode, operands);
3756 DONE;
3757}")
3758
3759(define_expand "xor_and_fetch_si"
3760 [(set (match_operand:SI 0 "register_operand" "r")
3761 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
3762 (match_operand:SI 2 "register_operand" "r")] 17))]
3763 ""
3764 "
3765{
3766 ia64_expand_op_and_fetch (IA64_XOR_OP, SImode, operands);
3767 DONE;
3768}")
3769
3770(define_expand "nand_and_fetch_si"
3771 [(set (match_operand:SI 0 "register_operand" "r")
3772 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
3773 (match_operand:SI 2 "register_operand" "r")] 17))]
3774 ""
3775 "
3776{
3777 ia64_expand_op_and_fetch (IA64_NAND_OP, SImode, operands);
3778 DONE;
3779}")
e5bde68a
RH
3780\f
3781;; Predication.
3782
3783(define_cond_exec
3784 [(match_operator 0 "predicate_operator"
3785 [(match_operand:CC 1 "register_operand" "c")
3786 (const_int 0)])]
3787 ""
3788 "(%J0)")
This page took 0.459952 seconds and 5 git commands to generate.