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