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