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