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