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