1 ;; IA-
64 Machine description template
2 ;; Copyright (C)
1999,
2000 Free Software Foundation, Inc.
3 ;; Contributed by James E. Wilson <wilson@cygnus.com> and
4 ;; David Mosberger <davidm@hpl.hp.com>.
6 ;; This file is part of GNU CC.
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)
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.
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.
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
25 ;; ??? register_operand accepts (subreg:DI (mem:SI X)) which forces later
26 ;; reload. This will be fixed once scheduling support is turned on.
28 ;; ??? Optimize for post-increment addressing modes.
30 ;; ??? fselect is not supported, because there is no integer register
33 ;; ??? fp abs/min/max instructions may also work for integer values.
35 ;; ??? Would a predicate_reg_operand predicate be useful? The HP one is buggy,
36 ;; it assumes the operand is a register and takes REGNO of it without checking.
38 ;; ??? Would a branch_reg_operand predicate be useful? The HP one is buggy,
39 ;; it assumes the operand is a register and takes REGNO of it without checking.
41 ;; ??? Go through list of documented named patterns and look for more to
44 ;; ??? Go through instruction manual and look for more instructions that
47 ;; ??? Add function unit scheduling info for Itanium (TM) processor.
49 ;; ??? The explicit stop in the flushrs pattern is not ideal. It
50 ;; would be better if rtx_needs_barrier took care of this, but this is
51 ;; something that can be fixed later.
70 ;;
2 insn_group_barrier
73 ;;
8 pred.safe_across_calls all
74 ;;
9 pred.safe_across_calls normal
76 ;; ::::::::::::::::::::
80 ;; ::::::::::::::::::::
82 ;; Instruction type. This primarily determines how instructions can be
83 ;; packed in bundles, and secondarily affects scheduling to function units.
85 ;; A alu, can go in I or M syllable of a bundle
90 ;; L long immediate, takes two syllables
93 ;; ??? Should not have any pattern with type unknown. Perhaps add code to
94 ;; check this in md_reorg? Currently use unknown for patterns which emit
95 ;; multiple instructions, patterns which emit
0 instructions, and patterns
96 ;; which emit instruction that can go in any slot (e.g. nop).
98 (define_attr "type" "unknown,A,I,M,F,B,L,S" (const_string "unknown"))
100 ;; Predication. True iff this instruction can be predicated.
102 (define_attr "predicable" "no,yes" (const_string "yes"))
105 ;; ::::::::::::::::::::
109 ;; ::::::::::::::::::::
111 ;; Each usage of a function units by a class of insns is specified with a
112 ;;
`define_function_unit' expression, which looks like this:
113 ;; (define_function_unit NAME MULTIPLICITY SIMULTANEITY TEST READY-DELAY
114 ;; ISSUE-DELAY [CONFLICT-LIST])
116 ;; This default scheduling info seeks to pack instructions into bundles
117 ;; efficiently to reduce code size, so we just list how many of each
118 ;; instruction type can go in a bundle. ISSUE_RATE is set to 3.
120 ;; ??? Add scheduler ready-list hook (MD_SCHED_REORDER) that orders
121 ;; instructions, so that the next instruction can fill the next bundle slot.
122 ;; This really needs to know where the stop bits are though.
124 ;; ??? Use MD_SCHED_REORDER to put alloc first instead of using an unspec
125 ;; volatile. Use ADJUST_PRIORITY to set the priority of alloc very high to
126 ;; make it schedule first.
128 ;; ??? Modify the md_reorg code that emits stop bits so that instead of putting
129 ;; them in the last possible place, we put them in places where bundles allow
130 ;; them. This should reduce code size, but may decrease performance if we end
131 ;; up with more stop bits than the minimum we need.
133 ;; Alu instructions can execute on either the integer or memory function
134 ;; unit. We indicate this by defining an alu function unit, and then marking
135 ;; it as busy everytime we issue a integer or memory type instruction.
137 (define_function_unit "alu" 3 1 (eq_attr "type" "A,I,M") 1 0)
139 (define_function_unit "integer" 2 1 (eq_attr "type" "I") 1 0)
141 (define_function_unit "memory" 3 1 (eq_attr "type" "M") 1 0)
143 (define_function_unit "floating_point" 1 1 (eq_attr "type" "F") 1 0)
145 (define_function_unit "branch" 3 1 (eq_attr "type" "B") 1 0)
147 ;; ??? This isn't quite right, because we can only fit two insns in a bundle
148 ;; when using an L type instruction. That isn't modeled currently.
150 (define_function_unit "long_immediate" 1 1 (eq_attr "type" "L") 1 0)
153 ;; ::::::::::::::::::::
157 ;; ::::::::::::::::::::
159 (define_expand "movqi"
160 [(set (match_operand:QI 0 "general_operand" "")
161 (match_operand:QI 1 "general_operand" ""))]
165 if (! reload_in_progress && ! reload_completed
166 && ! ia64_move_ok (operands[0], operands[1]))
167 operands[1] = force_reg (QImode, operands[1]);
170 ;; Errata 72 implies that we cannot use predicated loads and stores
171 ;; on affected systems. Reuse TARGET_A_STEP for convenience.
173 ;; ??? It would be convenient at this point if the cond_exec pattern
174 ;; expander understood non-constant conditions on attributes. Failing
175 ;; that we have to replicate patterns.
177 (define_insn "*movqicc_astep"
179 (match_operator 2 "predicate_operator"
180 [(match_operand:CC 3 "register_operand" "c,c,c,c,c")
182 (set (match_operand:QI 0 "register_operand" "=r,r, r,*f,*f")
183 (match_operand:QI 1 "nonmemory_operand" "rO,J,*f,rO,*f")))]
184 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
187 (%J2) addl %0 = %1, r0
188 (%J2) getf.sig %0 = %1
189 (%J2) setf.sig %0 = %r1
191 [(set_attr "type" "A,A,M,M,F")
192 (set_attr "predicable" "no")])
194 (define_insn "*movqi_internal_astep"
195 [(set (match_operand:QI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
196 (match_operand:QI 1 "move_operand" "rO,J,m,rO,*f,rO,*f"))]
197 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
206 [(set_attr "type" "A,A,M,M,M,M,F")
207 (set_attr "predicable" "no")])
209 (define_insn "*movqi_internal"
210 [(set (match_operand:QI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
211 (match_operand:QI 1 "move_operand" "rO,J,m,rO,*f,rO,*f"))]
212 "! TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
221 [(set_attr "type" "A,A,M,M,M,M,F")])
223 (define_expand "movhi"
224 [(set (match_operand:HI 0 "general_operand" "")
225 (match_operand:HI 1 "general_operand" ""))]
229 if (! reload_in_progress && ! reload_completed
230 && ! ia64_move_ok (operands[0], operands[1]))
231 operands[1] = force_reg (HImode, operands[1]);
234 ;; Errata 72 workaround.
235 (define_insn "*movhicc_astep"
237 (match_operator 2 "predicate_operator"
238 [(match_operand:CC 3 "register_operand" "c,c,c,c,c")
240 (set (match_operand:HI 0 "register_operand" "=r,r, r,*f,*f")
241 (match_operand:HI 1 "nonmemory_operand" "rO,J,*f,rO,*f")))]
242 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
245 (%J2) addl %0 = %1, r0
246 (%J2) getf.sig %0 = %1
247 (%J2) setf.sig %0 = %r1
249 [(set_attr "type" "A,A,M,M,F")
250 (set_attr "predicable" "no")])
252 (define_insn "*movhi_internal_astep"
253 [(set (match_operand:HI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
254 (match_operand:HI 1 "move_operand" "rO,J,m,rO,*f,rO,*f"))]
255 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
264 [(set_attr "type" "A,A,M,M,M,M,F")
265 (set_attr "predicable" "no")])
267 (define_insn "*movhi_internal"
268 [(set (match_operand:HI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
269 (match_operand:HI 1 "move_operand" "rO,J,m,rO,*f,rO,*f"))]
270 "! TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
279 [(set_attr "type" "A,A,M,M,M,M,F")])
281 (define_expand "movsi"
282 [(set (match_operand:SI 0 "general_operand" "")
283 (match_operand:SI 1 "general_operand" ""))]
287 if (! reload_in_progress && ! reload_completed
288 && ! ia64_move_ok (operands[0], operands[1]))
289 operands[1] = force_reg (SImode, operands[1]);
292 ;; Errata 72 workaround.
293 (define_insn "*movsicc_astep"
295 (match_operator 2 "predicate_operator"
296 [(match_operand:CC 3 "register_operand" "c,c,c,c,c,c,c,c")
298 (set (match_operand:SI 0 "register_operand" "=r,r,r, r,*f,*f, r,*d")
299 (match_operand:SI 1 "nonmemory_operand" "rO,J,i,*f,rO,*f,*d,rK")))]
300 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
303 (%J2) addl %0 = %1, r0
305 (%J2) getf.sig %0 = %1
306 (%J2) setf.sig %0 = %r1
310 [(set_attr "type" "A,A,L,M,M,F,M,M")
311 (set_attr "predicable" "no")])
313 (define_insn "*movsi_internal_astep"
314 [(set (match_operand:SI 0 "destination_operand" "=r,r,r,r, m, r,*f,*f, r,*d")
315 (match_operand:SI 1 "move_operand" "rO,J,i,m,rO,*f,rO,*f,*d,rK"))]
316 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
328 [(set_attr "type" "A,A,L,M,M,M,M,F,M,M")
329 (set_attr "predicable" "no")])
331 (define_insn "*movsi_internal"
332 [(set (match_operand:SI 0 "destination_operand" "=r,r,r,r, m, r,*f,*f, r,*d")
333 (match_operand:SI 1 "move_operand" "rO,J,i,m,rO,*f,rO,*f,*d,rK"))]
334 "! TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
346 [(set_attr "type" "A,A,L,M,M,M,M,F,M,M")])
348 (define_expand "movdi"
349 [(set (match_operand:DI 0 "general_operand" "")
350 (match_operand:DI 1 "general_operand" ""))]
354 if (! reload_in_progress && ! reload_completed
355 && ! ia64_move_ok (operands[0], operands[1]))
356 operands[1] = force_reg (DImode, operands[1]);
357 if (! TARGET_NO_PIC && symbolic_operand (operands[1], DImode))
359 /* Before optimization starts, delay committing to any particular
360 type of PIC address load. If this function gets deferred, we
361 may acquire information that changes the value of the
362 sdata_symbolic_operand predicate. */
363 /* But don't delay for function pointers. Loading a function address
364 actually loads the address of the descriptor not the function.
365 If we represent these as SYMBOL_REFs, then they get cse'd with
366 calls, and we end up with calls to the descriptor address instead of
367 calls to the function address. Functions are not candidates for
369 if (rtx_equal_function_value_matters
370 && ! (GET_CODE (operands[1]) == SYMBOL_REF
371 && SYMBOL_REF_FLAG (operands[1])))
372 emit_insn (gen_movdi_symbolic (operands[0], operands[1]));
374 ia64_expand_load_address (operands[0], operands[1]);
379 ;; Errata 72 workaround.
382 (match_operator 2 "predicate_operator"
383 [(match_operand:CC 3 "register_operand" "c,c,c,c,c,c,c,c,c,c,c")
385 (set (match_operand:DI 0 "register_operand"
386 "=r,r,r, r,*f,*f, r,*b,*e, r,*d")
387 (match_operand:DI 1 "nonmemory_operand"
388 "rO,J,i,*f,rO,*f,*b*e,rO,rK,*d,rK")))]
389 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
392 static const char * const alt[] = {
393 \"(%J2) mov %0 = %r1\",
394 \"(%J2) addl %0 = %1, r0\",
395 \"(%J2) movl %0 = %1\",
396 \"(%J2) getf.sig %0 = %1\",
397 \"(%J2) setf.sig %0 = %r1\",
398 \"(%J2) mov %0 = %1\",
399 \"(%J2) mov %0 = %1\",
400 \"(%J2) mov %0 = %r1\",
401 \"(%J2) mov %0 = %1\",
402 \"(%J2) mov %0 = %1\",
403 \"(%J2) mov %0 = %1\"
406 /* We use 'i' for alternative 2 despite possible PIC problems.
408 If we define LEGITIMATE_CONSTANT_P such that symbols are not
409 allowed, then the compiler dumps the data into constant memory
410 instead of letting us read the values from the GOT. Similarly
411 if we use 'n' instead of 'i'.
413 Instead, we allow such insns through reload and then split them
414 afterward (even without optimization). Therefore, we should
415 never get so far with a symbolic operand. */
417 if (which_alternative == 2 && ! TARGET_NO_PIC
418 && symbolic_operand (operands[1], VOIDmode))
421 return alt[which_alternative];
423 [(set_attr "type" "A,A,L,M,M,F,I,I,I,M,M")
424 (set_attr "predicable" "no")])
426 ;; This is used during early compilation to delay the decision on
427 ;; how to refer to a variable as long as possible. This is especially
428 ;; important between initial rtl generation and optimization for
429 ;; deferred functions, since we may acquire additional information
430 ;; on the variables used in the meantime.
432 (define_insn_and_split "movdi_symbolic"
433 [(set (match_operand:DI 0 "register_operand" "=r")
434 (match_operand:DI 1 "symbolic_operand" "s"))
440 "ia64_expand_load_address (operands[0], operands[1]); DONE;")
442 (define_insn "*movdi_internal_astep"
443 [(set (match_operand:DI 0 "destination_operand"
444 "=r,r,r,r, m, r,*f,*f,*f, Q, r,*b,*e, r,*d, r,*c")
445 (match_operand:DI 1 "move_operand"
446 "rO,J,i,m,rO,*f,rO,*f, Q,*f,*b*e,rO,rK,*d,rK,*c,rO"))]
447 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
450 static const char * const alt[] = {
452 \"addl %0 = %1, r0\",
454 \"ld8%O1 %0 = %1%P1\",
455 \"st8%Q0 %0 = %r1%P0\",
456 \"getf.sig %0 = %1\",
457 \"setf.sig %0 = %r1\",
470 if (which_alternative == 2 && ! TARGET_NO_PIC
471 && symbolic_operand (operands[1], VOIDmode))
474 return alt[which_alternative];
476 [(set_attr "type" "A,A,L,M,M,M,M,F,M,M,I,I,I,M,M,I,I")
477 (set_attr "predicable" "no")])
479 (define_insn "*movdi_internal"
480 [(set (match_operand:DI 0 "destination_operand"
481 "=r,r,r,r, m, r,*f,*f,*f, Q, r,*b,*e, r,*d, r,*c")
482 (match_operand:DI 1 "move_operand"
483 "rO,J,i,m,rO,*f,rO,*f, Q,*f,*b*e,rO,rK,*d,rK,*c,rO"))]
484 "! TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
487 static const char * const alt[] = {
489 \"%,addl %0 = %1, r0\",
491 \"%,ld8%O1 %0 = %1%P1\",
492 \"%,st8%Q0 %0 = %r1%P0\",
493 \"%,getf.sig %0 = %1\",
494 \"%,setf.sig %0 = %r1\",
496 \"%,ldf8 %0 = %1%P1\",
497 \"%,stf8 %0 = %1%P0\",
507 if (which_alternative == 2 && ! TARGET_NO_PIC
508 && symbolic_operand (operands[1], VOIDmode))
511 return alt[which_alternative];
513 [(set_attr "type" "A,A,L,M,M,M,M,F,M,M,I,I,I,M,M,I,I")])
516 [(set (match_operand:DI 0 "register_operand" "")
517 (match_operand:DI 1 "symbolic_operand" ""))]
518 "reload_completed && ! TARGET_NO_PIC"
522 ia64_expand_load_address (operands[0], operands[1]);
526 (define_expand "load_fptr"
528 (plus:DI (reg:DI 1) (match_operand:DI 1 "function_operand" "")))
529 (set (match_operand:DI 0 "register_operand" "") (match_dup 3))]
533 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
534 operands[3] = gen_rtx_MEM (DImode, operands[2]);
535 RTX_UNCHANGING_P (operands[3]) = 1;
538 (define_insn "*load_fptr_internal1"
539 [(set (match_operand:DI 0 "register_operand" "=r")
540 (plus:DI (reg:DI 1) (match_operand:DI 1 "function_operand" "s")))]
542 "addl %0 = @ltoff(@fptr(%1)), gp"
543 [(set_attr "type" "A")])
545 (define_insn "load_gprel"
546 [(set (match_operand:DI 0 "register_operand" "=r")
547 (plus:DI (reg:DI 1) (match_operand:DI 1 "sdata_symbolic_operand" "s")))]
549 "addl %0 = @gprel(%1), gp"
550 [(set_attr "type" "A")])
552 (define_insn "gprel64_offset"
553 [(set (match_operand:DI 0 "register_operand" "=r")
554 (minus:DI (match_operand:DI 1 "symbolic_operand" "") (reg:DI 1)))]
556 "movl %0 = @gprel(%1)"
557 [(set_attr "type" "L")])
559 (define_expand "load_gprel64"
561 (minus:DI (match_operand:DI 1 "symbolic_operand" "") (reg:DI 1)))
562 (set (match_operand:DI 0 "register_operand" "")
563 (plus:DI (reg:DI 1) (match_dup 2)))]
567 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
570 (define_expand "load_symptr"
572 (plus:DI (reg:DI 1) (match_operand:DI 1 "got_symbolic_operand" "")))
573 (set (match_operand:DI 0 "register_operand" "") (match_dup 3))]
577 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
578 operands[3] = gen_rtx_MEM (DImode, operands[2]);
579 RTX_UNCHANGING_P (operands[3]) = 1;
582 (define_insn "*load_symptr_internal1"
583 [(set (match_operand:DI 0 "register_operand" "=r")
584 (plus:DI (reg:DI 1) (match_operand:DI 1 "got_symbolic_operand" "s")))]
586 "addl %0 = @ltoff(%1), gp"
587 [(set_attr "type" "A")])
589 ;; With no offsettable memory references, we've got to have a scratch
590 ;; around to play with the second word.
591 (define_expand "movti"
592 [(parallel [(set (match_operand:TI 0 "general_operand" "")
593 (match_operand:TI 1 "general_operand" ""))
594 (clobber (match_scratch:DI 2 ""))])]
598 if (! reload_in_progress && ! reload_completed
599 && ! ia64_move_ok (operands[0], operands[1]))
600 operands[1] = force_reg (TImode, operands[1]);
603 (define_insn_and_split "*movti_internal"
604 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m")
605 (match_operand:TI 1 "general_operand" "ri,m,r"))
606 (clobber (match_scratch:DI 2 "=X,&r,&r"))]
607 "ia64_move_ok (operands[0], operands[1])"
613 rtx adj1, adj2, in[2], out[2];
616 adj1 = ia64_split_timode (in, operands[1], operands[2]);
617 adj2 = ia64_split_timode (out, operands[0], operands[2]);
620 if (reg_overlap_mentioned_p (out[0], in[1]))
622 if (reg_overlap_mentioned_p (out[1], in[0]))
633 emit_insn (gen_rtx_SET (VOIDmode, out[first], in[first]));
634 emit_insn (gen_rtx_SET (VOIDmode, out[!first], in[!first]));
637 [(set_attr "type" "unknown")
638 (set_attr "predicable" "no")])
640 ;; ??? SSA creates these. Can't allow memories since we don't have
641 ;; the scratch register. Fortunately combine will know how to add
642 ;; the clobber and scratch.
643 (define_insn_and_split "*movti_internal_reg"
644 [(set (match_operand:TI 0 "register_operand" "=r")
645 (match_operand:TI 1 "nonmemory_operand" "ri"))]
655 ia64_split_timode (in, operands[1], NULL_RTX);
656 ia64_split_timode (out, operands[0], NULL_RTX);
659 if (reg_overlap_mentioned_p (out[0], in[1]))
661 if (reg_overlap_mentioned_p (out[1], in[0]))
666 emit_insn (gen_rtx_SET (VOIDmode, out[first], in[first]));
667 emit_insn (gen_rtx_SET (VOIDmode, out[!first], in[!first]));
670 [(set_attr "type" "unknown")
671 (set_attr "predicable" "no")])
673 (define_expand "reload_inti"
674 [(parallel [(set (match_operand:TI 0 "register_operand" "=r")
675 (match_operand:TI 1 "" "m"))
676 (clobber (match_operand:TI 2 "register_operand" "=&r"))])]
680 unsigned int s_regno = REGNO (operands[2]);
681 if (s_regno == REGNO (operands[0]))
683 operands[2] = gen_rtx_REG (DImode, s_regno);
686 (define_expand "reload_outti"
687 [(parallel [(set (match_operand:TI 0 "" "=m")
688 (match_operand:TI 1 "register_operand" "r"))
689 (clobber (match_operand:TI 2 "register_operand" "=&r"))])]
693 unsigned int s_regno = REGNO (operands[2]);
694 if (s_regno == REGNO (operands[1]))
696 operands[2] = gen_rtx_REG (DImode, s_regno);
699 ;; Floating Point Moves
701 ;; Note - Patterns for SF mode moves are compulsory, but
702 ;; patterns for DF are optional, as GCC can synthesise them.
704 (define_expand "movsf"
705 [(set (match_operand:SF 0 "general_operand" "")
706 (match_operand:SF 1 "general_operand" ""))]
710 if (! reload_in_progress && ! reload_completed
711 && ! ia64_move_ok (operands[0], operands[1]))
712 operands[1] = force_reg (SFmode, operands[1]);
715 ;; Errata 72 workaround.
716 (define_insn "*movsfcc_astep"
718 (match_operator 2 "predicate_operator"
719 [(match_operand:CC 3 "register_operand" "c,c,c,c")
721 (set (match_operand:SF 0 "register_operand" "=f,*r, f,*r")
722 (match_operand:SF 1 "nonmemory_operand" "fG,fG,*r,*r")))]
723 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
726 (%J2) getf.s %0 = %F1
729 [(set_attr "type" "F,M,M,A")
730 (set_attr "predicable" "no")])
732 (define_insn "*movsf_internal_astep"
733 [(set (match_operand:SF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m")
734 (match_operand:SF 1 "general_operand" "fG,Q,fG,fG,*r,*r, m,*r"))]
735 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
745 [(set_attr "type" "F,M,M,M,M,A,M,M")
746 (set_attr "predicable" "no")])
748 (define_insn "*movsf_internal"
749 [(set (match_operand:SF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m")
750 (match_operand:SF 1 "general_operand" "fG,Q,fG,fG,*r,*r, m,*r"))]
751 "! TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
761 [(set_attr "type" "F,M,M,M,M,A,M,M")])
763 (define_expand "movdf"
764 [(set (match_operand:DF 0 "general_operand" "")
765 (match_operand:DF 1 "general_operand" ""))]
769 if (! reload_in_progress && ! reload_completed
770 && ! ia64_move_ok (operands[0], operands[1]))
771 operands[1] = force_reg (DFmode, operands[1]);
774 ;; Errata 72 workaround.
775 (define_insn "*movdfcc_astep"
777 (match_operator 2 "predicate_operator"
778 [(match_operand:CC 3 "register_operand" "c,c,c,c")
780 (set (match_operand:DF 0 "register_operand" "=f,*r, f,*r")
781 (match_operand:DF 1 "nonmemory_operand" "fG,fG,*r,*r")))]
782 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
785 (%J2) getf.d %0 = %F1
788 [(set_attr "type" "F,M,M,A")
789 (set_attr "predicable" "no")])
791 (define_insn "*movdf_internal_astep"
792 [(set (match_operand:DF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m")
793 (match_operand:DF 1 "general_operand" "fG,Q,fG,fG,*r,*r, m,*r"))]
794 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
804 [(set_attr "type" "F,M,M,M,M,A,M,M")
805 (set_attr "predicable" "no")])
807 (define_insn "*movdf_internal"
808 [(set (match_operand:DF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m")
809 (match_operand:DF 1 "general_operand" "fG,Q,fG,fG,*r,*r, m,*r"))]
810 "! TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
820 [(set_attr "type" "F,M,M,M,M,A,M,M")])
822 ;; With no offsettable memory references, we've got to have a scratch
823 ;; around to play with the second word if the variable winds up in GRs.
824 (define_expand "movtf"
825 [(set (match_operand:TF 0 "general_operand" "")
826 (match_operand:TF 1 "general_operand" ""))]
830 /* We must support TFmode loads into general registers for stdarg/vararg
831 and unprototyped calls. We split them into DImode loads for convenience.
832 We don't need TFmode stores from general regs, because a stdarg/vararg
833 routine does a block store to memory of unnamed arguments. */
834 if (GET_CODE (operands[0]) == REG
835 && GR_REGNO_P (REGNO (operands[0])))
837 /* We're hoping to transform everything that deals with TFmode
838 quantities and GR registers early in the compiler. */
842 /* Struct to register can just use TImode instead. */
843 if ((GET_CODE (operands[1]) == SUBREG
844 && GET_MODE (SUBREG_REG (operands[1])) == TImode)
845 || (GET_CODE (operands[1]) == REG
846 && GR_REGNO_P (REGNO (operands[1]))))
848 emit_move_insn (gen_rtx_REG (TImode, REGNO (operands[0])),
849 SUBREG_REG (operands[1]));
853 if (GET_CODE (operands[1]) == CONST_DOUBLE)
855 emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0])),
856 operand_subword (operands[1], 0, 0, DImode));
857 emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0]) + 1),
858 operand_subword (operands[1], 1, 0, DImode));
862 /* If the quantity is in a register not known to be GR, spill it. */
863 if (register_operand (operands[1], TFmode))
864 operands[1] = spill_tfmode_operand (operands[1], 1);
866 if (GET_CODE (operands[1]) == MEM)
870 out[WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[0]));
871 out[!WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[0])+1);
873 emit_move_insn (out[0], change_address (operands[1], DImode, NULL));
874 emit_move_insn (out[1],
875 change_address (operands[1], DImode,
876 plus_constant (XEXP (operands[1], 0),
884 if (! reload_in_progress && ! reload_completed)
886 operands[0] = spill_tfmode_operand (operands[0], 0);
887 operands[1] = spill_tfmode_operand (operands[1], 0);
889 if (! ia64_move_ok (operands[0], operands[1]))
890 operands[1] = force_reg (TFmode, operands[1]);
894 ;; ??? There's no easy way to mind volatile acquire/release semantics.
896 ;; Errata 72 workaround.
897 (define_insn "*movtfcc_astep"
899 (match_operator 2 "predicate_operator"
900 [(match_operand:CC 3 "register_operand" "c")
902 (set (match_operand:TF 0 "register_operand" "=f")
903 (match_operand:TF 1 "nonmemory_operand" "fG")))]
904 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
906 [(set_attr "type" "F")
907 (set_attr "predicable" "no")])
909 (define_insn "*movtf_internal_astep"
910 [(set (match_operand:TF 0 "destination_tfmode_operand" "=f,f, m")
911 (match_operand:TF 1 "general_tfmode_operand" "fG,m,fG"))]
912 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
917 [(set_attr "type" "F,M,M")
918 (set_attr "predicable" "no")])
920 (define_insn "*movtf_internal"
921 [(set (match_operand:TF 0 "destination_tfmode_operand" "=f,f, m")
922 (match_operand:TF 1 "general_tfmode_operand" "fG,m,fG"))]
923 "! TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
928 [(set_attr "type" "F,M,M")])
930 ;; ::::::::::::::::::::
934 ;; ::::::::::::::::::::
936 ;; Signed conversions from a smaller integer to a larger integer
938 (define_insn "extendqidi2"
939 [(set (match_operand:DI 0 "gr_register_operand" "=r")
940 (sign_extend:DI (match_operand:QI 1 "gr_register_operand" "r")))]
943 [(set_attr "type" "I")])
945 (define_insn "extendhidi2"
946 [(set (match_operand:DI 0 "gr_register_operand" "=r")
947 (sign_extend:DI (match_operand:HI 1 "gr_register_operand" "r")))]
950 [(set_attr "type" "I")])
952 (define_insn "extendsidi2"
953 [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
954 (sign_extend:DI (match_operand:SI 1 "grfr_register_operand" "r,*f")))]
958 fsxt.r %0 = %1, %1%B0"
959 [(set_attr "type" "I,F")])
961 ;; Unsigned conversions from a smaller integer to a larger integer
963 (define_insn "zero_extendqidi2"
964 [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
965 (zero_extend:DI (match_operand:QI 1 "gr_nonimmediate_operand" "r,m")))]
970 [(set_attr "type" "I,M")])
972 (define_insn "zero_extendhidi2"
973 [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
974 (zero_extend:DI (match_operand:HI 1 "gr_nonimmediate_operand" "r,m")))]
979 [(set_attr "type" "I,M")])
981 (define_insn "zero_extendsidi2"
982 [(set (match_operand:DI 0 "grfr_register_operand" "=r,r,*f")
984 (match_operand:SI 1 "grfr_nonimmediate_operand" "r,m,*f")))]
989 fsxt.r %0 = f1, %1%B0"
990 [(set_attr "type" "I,M,F")])
992 ;; Convert between floating point types of different sizes.
994 ;; ??? Optimization opportunity here. Get rid of the insn altogether
995 ;; when we can. Should probably use a scheme like has been proposed
996 ;; for ia32 in dealing with operands that match unary operators. This
997 ;; would let combine merge the thing into adjacent insns.
999 (define_insn_and_split "extendsfdf2"
1000 [(set (match_operand:DF 0 "fr_register_operand" "=f,f")
1001 (float_extend:DF (match_operand:SF 1 "fr_register_operand" "0,f")))]
1005 [(set (match_dup 0) (float_extend:DF (match_dup 1)))]
1006 "if (true_regnum (operands[0]) == true_regnum (operands[1])) DONE;"
1007 [(set_attr "type" "F")])
1009 (define_insn_and_split "extendsftf2"
1010 [(set (match_operand:TF 0 "fr_register_operand" "=f,f")
1011 (float_extend:TF (match_operand:SF 1 "fr_register_operand" "0,f")))]
1015 [(set (match_dup 0) (float_extend:TF (match_dup 1)))]
1016 "if (true_regnum (operands[0]) == true_regnum (operands[1])) DONE;"
1017 [(set_attr "type" "F")])
1019 (define_insn_and_split "extenddftf2"
1020 [(set (match_operand:TF 0 "fr_register_operand" "=f,f")
1021 (float_extend:TF (match_operand:DF 1 "fr_register_operand" "0,f")))]
1025 [(set (match_dup 0) (float_extend:TF (match_dup 1)))]
1026 "if (true_regnum (operands[0]) == true_regnum (operands[1])) DONE;"
1027 [(set_attr "type" "F")])
1029 (define_insn "truncdfsf2"
1030 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1031 (float_truncate:SF (match_operand:DF 1 "fr_register_operand" "f")))]
1033 "fnorm.s %0 = %1%B0"
1034 [(set_attr "type" "F")])
1036 (define_insn "trunctfsf2"
1037 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1038 (float_truncate:SF (match_operand:TF 1 "fr_register_operand" "f")))]
1040 "fnorm.s %0 = %1%B0"
1041 [(set_attr "type" "F")])
1043 (define_insn "trunctfdf2"
1044 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1045 (float_truncate:DF (match_operand:TF 1 "fr_register_operand" "f")))]
1047 "fnorm.d %0 = %1%B0"
1048 [(set_attr "type" "F")])
1050 ;; Convert between signed integer types and floating point.
1052 (define_insn "floatditf2"
1053 [(set (match_operand:TF 0 "fr_register_operand" "=f")
1054 (float:TF (match_operand:DI 1 "fr_register_operand" "f")))]
1057 [(set_attr "type" "F")])
1059 (define_insn "fix_truncsfdi2"
1060 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1061 (fix:DI (match_operand:SF 1 "fr_register_operand" "f")))]
1063 "fcvt.fx.trunc %0 = %1%B0"
1064 [(set_attr "type" "F")])
1066 (define_insn "fix_truncdfdi2"
1067 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1068 (fix:DI (match_operand:DF 1 "fr_register_operand" "f")))]
1070 "fcvt.fx.trunc %0 = %1%B0"
1071 [(set_attr "type" "F")])
1073 (define_insn "fix_trunctfdi2"
1074 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1075 (fix:DI (match_operand:TF 1 "fr_register_operand" "f")))]
1077 "fcvt.fx.trunc %0 = %1%B0"
1078 [(set_attr "type" "F")])
1080 ;; Convert between unsigned integer types and floating point.
1082 (define_insn "floatunsdisf2"
1083 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1084 (unsigned_float:SF (match_operand:DI 1 "fr_register_operand" "f")))]
1086 "fcvt.xuf.s %0 = %1%B0"
1087 [(set_attr "type" "F")])
1089 (define_insn "floatunsdidf2"
1090 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1091 (unsigned_float:DF (match_operand:DI 1 "fr_register_operand" "f")))]
1093 "fcvt.xuf.d %0 = %1%B0"
1094 [(set_attr "type" "F")])
1096 (define_insn "floatunsditf2"
1097 [(set (match_operand:TF 0 "fr_register_operand" "=f")
1098 (unsigned_float:TF (match_operand:DI 1 "fr_register_operand" "f")))]
1100 "fcvt.xuf %0 = %1%B0"
1101 [(set_attr "type" "F")])
1103 (define_insn "fixuns_truncsfdi2"
1104 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1105 (unsigned_fix:DI (match_operand:SF 1 "fr_register_operand" "f")))]
1107 "fcvt.fxu.trunc %0 = %1%B0"
1108 [(set_attr "type" "F")])
1110 (define_insn "fixuns_truncdfdi2"
1111 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1112 (unsigned_fix:DI (match_operand:DF 1 "fr_register_operand" "f")))]
1114 "fcvt.fxu.trunc %0 = %1%B0"
1115 [(set_attr "type" "F")])
1117 (define_insn "fixuns_trunctfdi2"
1118 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1119 (unsigned_fix:DI (match_operand:TF 1 "fr_register_operand" "f")))]
1121 "fcvt.fxu.trunc %0 = %1%B0"
1122 [(set_attr "type" "F")])
1124 ;; ::::::::::::::::::::
1126 ;; :: Bit field extraction
1128 ;; ::::::::::::::::::::
1131 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1132 (sign_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
1133 (match_operand:DI 2 "const_int_operand" "n")
1134 (match_operand:DI 3 "const_int_operand" "n")))]
1136 "extr %0 = %1, %3, %2"
1137 [(set_attr "type" "I")])
1139 (define_insn "extzv"
1140 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1141 (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
1142 (match_operand:DI 2 "const_int_operand" "n")
1143 (match_operand:DI 3 "const_int_operand" "n")))]
1145 "extr.u %0 = %1, %3, %2"
1146 [(set_attr "type" "I")])
1148 ;; Insert a bit field.
1149 ;; Can have 3 operands, source1 (inserter), source2 (insertee), dest.
1150 ;; Source1 can be 0 or -1.
1151 ;; Source2 can be 0.
1153 ;; ??? Actual dep instruction is more powerful than what these insv
1154 ;; patterns support. Unfortunately, combine is unable to create patterns
1155 ;; where source2 != dest.
1157 (define_expand "insv"
1158 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "")
1159 (match_operand:DI 1 "const_int_operand" "")
1160 (match_operand:DI 2 "const_int_operand" ""))
1161 (match_operand:DI 3 "nonmemory_operand" ""))]
1165 int width = INTVAL (operands[1]);
1166 int shift = INTVAL (operands[2]);
1168 /* If operand[3] is a constant, and isn't 0 or -1, then load it into a
1170 if (! register_operand (operands[3], DImode)
1171 && operands[3] != const0_rtx && operands[3] != constm1_rtx)
1172 operands[3] = force_reg (DImode, operands[3]);
1174 /* If this is a single dep instruction, we have nothing to do. */
1175 if (! ((register_operand (operands[3], DImode) && width <= 16)
1176 || operands[3] == const0_rtx || operands[3] == constm1_rtx))
1178 /* Check for cases that can be implemented with a mix instruction. */
1179 if (width == 32 && shift == 0)
1181 /* Directly generating the mix4left instruction confuses
1182 optimize_bit_field in function.c. Since this is performing
1183 a useful optimization, we defer generation of the complicated
1184 mix4left RTL to the first splitting phase. */
1185 rtx tmp = gen_reg_rtx (DImode);
1186 emit_insn (gen_shift_mix4left (operands[0], operands[3], tmp));
1189 else if (width == 32 && shift == 32)
1191 emit_insn (gen_mix4right (operands[0], operands[3]));
1195 /* We could handle remaining cases by emitting multiple dep
1198 If we need more than two dep instructions then we lose. A 6
1199 insn sequence mov mask1,mov mask2,shl;;and,and;;or is better than
1200 mov;;dep,shr;;dep,shr;;dep. The former can be executed in 3 cycles,
1201 the latter is 6 cycles on an Itanium (TM) processor, because there is
1202 only one function unit that can execute dep and shr immed.
1204 If we only need two dep instruction, then we still lose.
1205 mov;;dep,shr;;dep is still 4 cycles. Even if we optimize away
1206 the unnecessary mov, this is still undesirable because it will be
1207 hard to optimize, and it creates unnecessary pressure on the I0
1213 /* This code may be useful for other IA-64 processors, so we leave it in
1219 emit_insn (gen_insv (operands[0], GEN_INT (16), GEN_INT (shift),
1223 tmp = gen_reg_rtx (DImode);
1224 emit_insn (gen_lshrdi3 (tmp, operands[3], GEN_INT (16)));
1227 operands[1] = GEN_INT (width);
1228 operands[2] = GEN_INT (shift);
1233 (define_insn "*insv_internal"
1234 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
1235 (match_operand:DI 1 "const_int_operand" "n")
1236 (match_operand:DI 2 "const_int_operand" "n"))
1237 (match_operand:DI 3 "nonmemory_operand" "rP"))]
1238 "(gr_register_operand (operands[3], DImode) && INTVAL (operands[1]) <= 16)
1239 || operands[3] == const0_rtx || operands[3] == constm1_rtx"
1240 "dep %0 = %3, %0, %2, %1"
1241 [(set_attr "type" "I")])
1243 ;; Combine doesn't like to create bitfield insertions into zero.
1244 (define_insn "*depz_internal"
1245 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1246 (and:DI (ashift:DI (match_operand:DI 1 "gr_register_operand" "r")
1247 (match_operand:DI 2 "const_int_operand" "n"))
1248 (match_operand:DI 3 "const_int_operand" "n")))]
1249 "CONST_OK_FOR_M (INTVAL (operands[2]))
1250 && ia64_depz_field_mask (operands[3], operands[2]) > 0"
1253 operands[3] = GEN_INT (ia64_depz_field_mask (operands[3], operands[2]));
1254 return \"%,dep.z %0 = %1, %2, %3\";
1256 [(set_attr "type" "I")])
1258 (define_insn "shift_mix4left"
1259 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
1260 (const_int 32) (const_int 0))
1261 (match_operand:DI 1 "gr_register_operand" "r"))
1262 (clobber (match_operand:DI 2 "gr_register_operand" "=r"))]
1265 [(set_attr "type" "unknown")])
1268 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
1269 (const_int 32) (const_int 0))
1270 (match_operand:DI 1 "register_operand" ""))
1271 (clobber (match_operand:DI 2 "register_operand" ""))]
1273 [(set (match_dup 3) (ashift:DI (match_dup 1) (const_int 32)))
1274 (unspec_volatile [(const_int 0)] 2)
1275 (set (zero_extract:DI (match_dup 0) (const_int 32) (const_int 0))
1276 (lshiftrt:DI (match_dup 3) (const_int 32)))]
1277 "operands[3] = operands[2];")
1280 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
1281 (const_int 32) (const_int 0))
1282 (match_operand:DI 1 "register_operand" ""))
1283 (clobber (match_operand:DI 2 "register_operand" ""))]
1284 "! reload_completed"
1285 [(set (match_dup 3) (ashift:DI (match_dup 1) (const_int 32)))
1286 (set (zero_extract:DI (match_dup 0) (const_int 32) (const_int 0))
1287 (lshiftrt:DI (match_dup 3) (const_int 32)))]
1288 "operands[3] = operands[2];")
1290 (define_insn "*mix4left"
1291 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
1292 (const_int 32) (const_int 0))
1293 (lshiftrt:DI (match_operand:DI 1 "gr_register_operand" "r")
1296 "mix4.l %0 = %0, %r1"
1297 [(set_attr "type" "I")])
1299 (define_insn "mix4right"
1300 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
1301 (const_int 32) (const_int 32))
1302 (match_operand:DI 1 "gr_reg_or_0_operand" "rO"))]
1304 "mix4.r %0 = %r1, %0"
1305 [(set_attr "type" "I")])
1307 ;; This is used by the rotrsi3 pattern.
1309 (define_insn "*mix4right_3op"
1310 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1311 (ior:DI (zero_extend:DI (match_operand:SI 1 "gr_register_operand" "r"))
1312 (ashift:DI (zero_extend:DI
1313 (match_operand:SI 2 "gr_register_operand" "r"))
1316 "mix4.r %0 = %2, %1"
1317 [(set_attr "type" "I")])
1320 ;; ::::::::::::::::::::
1322 ;; :: 16 bit Integer arithmetic
1324 ;; ::::::::::::::::::::
1326 (define_insn "mulhi3"
1327 [(set (match_operand:HI 0 "gr_register_operand" "=r")
1328 (mult:HI (match_operand:HI 1 "gr_register_operand" "r")
1329 (match_operand:HI 2 "gr_register_operand" "r")))]
1331 "pmpy.r %0 = %1, %2"
1332 [(set_attr "type" "I")])
1335 ;; ::::::::::::::::::::
1337 ;; :: 32 bit Integer arithmetic
1339 ;; ::::::::::::::::::::
1341 (define_insn "addsi3"
1342 [(set (match_operand:SI 0 "gr_register_operand" "=r,r,r")
1343 (plus:SI (match_operand:SI 1 "gr_register_operand" "%r,r,a")
1344 (match_operand:SI 2 "gr_reg_or_22bit_operand" "r,I,J")))]
1350 [(set_attr "type" "A")])
1352 (define_insn "*addsi3_plus1"
1353 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1354 (plus:SI (plus:SI (match_operand:SI 1 "gr_register_operand" "r")
1355 (match_operand:SI 2 "gr_register_operand" "r"))
1358 "add %0 = %1, %2, 1"
1359 [(set_attr "type" "A")])
1361 (define_insn "*addsi3_plus1_alt"
1362 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1363 (plus:SI (mult:SI (match_operand:SI 1 "gr_register_operand" "r")
1367 "add %0 = %1, %1, 1"
1368 [(set_attr "type" "A")])
1370 (define_insn "*addsi3_shladd"
1371 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1372 (plus:SI (mult:SI (match_operand:SI 1 "gr_register_operand" "r")
1373 (match_operand:SI 2 "shladd_operand" "n"))
1374 (match_operand:SI 3 "gr_register_operand" "r")))]
1376 "shladd %0 = %1, %S2, %3"
1377 [(set_attr "type" "A")])
1379 (define_insn "subsi3"
1380 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1381 (minus:SI (match_operand:SI 1 "gr_reg_or_8bit_operand" "rK")
1382 (match_operand:SI 2 "gr_register_operand" "r")))]
1385 [(set_attr "type" "A")])
1387 (define_insn "*subsi3_minus1"
1388 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1389 (plus:SI (not:SI (match_operand:SI 1 "gr_register_operand" "r"))
1390 (match_operand:SI 2 "gr_register_operand" "r")))]
1392 "sub %0 = %2, %1, 1"
1393 [(set_attr "type" "A")])
1395 (define_insn "mulsi3"
1396 [(set (match_operand:SI 0 "fr_register_operand" "=f")
1397 (mult:SI (match_operand:SI 1 "grfr_register_operand" "f")
1398 (match_operand:SI 2 "grfr_register_operand" "f")))]
1400 "xma.l %0 = %1, %2, f0%B0"
1401 [(set_attr "type" "F")])
1403 (define_insn "*maddsi3"
1404 [(set (match_operand:SI 0 "fr_register_operand" "=f")
1405 (plus:SI (mult:SI (match_operand:SI 1 "grfr_register_operand" "f")
1406 (match_operand:SI 2 "grfr_register_operand" "f"))
1407 (match_operand:SI 3 "grfr_register_operand" "f")))]
1409 "xma.l %0 = %1, %2, %3%B0"
1410 [(set_attr "type" "F")])
1412 (define_insn "negsi2"
1413 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1414 (neg:SI (match_operand:SI 1 "gr_register_operand" "r")))]
1417 [(set_attr "type" "A")])
1419 (define_expand "abssi2"
1421 (ge:CC (match_operand:SI 1 "gr_register_operand" "") (const_int 0)))
1422 (set (match_operand:SI 0 "gr_register_operand" "")
1423 (if_then_else:SI (eq:CC (match_dup 2) (const_int 0))
1424 (neg:SI (match_dup 1))
1429 operands[2] = gen_reg_rtx (CCmode);
1432 (define_expand "sminsi3"
1434 (ge:CC (match_operand:SI 1 "gr_register_operand" "")
1435 (match_operand:SI 2 "gr_register_operand" "")))
1436 (set (match_operand:SI 0 "gr_register_operand" "")
1437 (if_then_else:SI (ne:CC (match_dup 3) (const_int 0))
1438 (match_dup 2) (match_dup 1)))]
1442 operands[3] = gen_reg_rtx (CCmode);
1445 (define_expand "smaxsi3"
1447 (ge:CC (match_operand:SI 1 "gr_register_operand" "")
1448 (match_operand:SI 2 "gr_register_operand" "")))
1449 (set (match_operand:SI 0 "gr_register_operand" "")
1450 (if_then_else:SI (ne:CC (match_dup 3) (const_int 0))
1451 (match_dup 1) (match_dup 2)))]
1455 operands[3] = gen_reg_rtx (CCmode);
1458 (define_expand "uminsi3"
1460 (geu:CC (match_operand:SI 1 "gr_register_operand" "")
1461 (match_operand:SI 2 "gr_register_operand" "")))
1462 (set (match_operand:SI 0 "gr_register_operand" "")
1463 (if_then_else:SI (ne:CC (match_dup 3) (const_int 0))
1464 (match_dup 2) (match_dup 1)))]
1468 operands[3] = gen_reg_rtx (CCmode);
1471 (define_expand "umaxsi3"
1473 (geu:CC (match_operand:SI 1 "gr_register_operand" "")
1474 (match_operand:SI 2 "gr_register_operand" "")))
1475 (set (match_operand:SI 0 "gr_register_operand" "")
1476 (if_then_else:SI (ne:CC (match_dup 3) (const_int 0))
1477 (match_dup 1) (match_dup 2)))]
1481 operands[3] = gen_reg_rtx (CCmode);
1485 ;; ::::::::::::::::::::
1487 ;; :: 64 bit Integer arithmetic
1489 ;; ::::::::::::::::::::
1491 (define_insn "adddi3"
1492 [(set (match_operand:DI 0 "gr_register_operand" "=r,r,r")
1493 (plus:DI (match_operand:DI 1 "gr_register_operand" "%r,r,a")
1494 (match_operand:DI 2 "gr_reg_or_22bit_operand" "r,I,J")))]
1500 [(set_attr "type" "A")])
1502 (define_insn "*adddi3_plus1"
1503 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1504 (plus:DI (plus:DI (match_operand:DI 1 "gr_register_operand" "r")
1505 (match_operand:DI 2 "gr_register_operand" "r"))
1508 "add %0 = %1, %2, 1"
1509 [(set_attr "type" "A")])
1511 ;; This has some of the same problems as shladd. We let the shladd
1512 ;; eliminator hack handle it, which results in the 1 being forced into
1513 ;; a register, but not more ugliness here.
1514 (define_insn "*adddi3_plus1_alt"
1515 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1516 (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
1520 "add %0 = %1, %1, 1"
1521 [(set_attr "type" "A")])
1523 (define_insn "subdi3"
1524 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1525 (minus:DI (match_operand:DI 1 "gr_reg_or_8bit_operand" "rK")
1526 (match_operand:DI 2 "gr_register_operand" "r")))]
1529 [(set_attr "type" "A")])
1531 (define_insn "*subdi3_minus1"
1532 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1533 (plus:DI (not:DI (match_operand:DI 1 "gr_register_operand" "r"))
1534 (match_operand:DI 2 "gr_register_operand" "r")))]
1536 "sub %0 = %2, %1, 1"
1537 [(set_attr "type" "A")])
1539 ;; ??? Use grfr instead of fr because of virtual register elimination
1540 ;; and silly test cases multiplying by the frame pointer.
1541 (define_insn "muldi3"
1542 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1543 (mult:DI (match_operand:DI 1 "grfr_register_operand" "f")
1544 (match_operand:DI 2 "grfr_register_operand" "f")))]
1546 "xma.l %0 = %1, %2, f0%B0"
1547 [(set_attr "type" "F")])
1549 ;; ??? If operand 3 is an eliminable reg, then register elimination causes the
1550 ;; same problem that we have with shladd below. Unfortunately, this case is
1551 ;; much harder to fix because the multiply puts the result in an FP register,
1552 ;; but the add needs inputs from a general register. We add a spurious clobber
1553 ;; here so that it will be present just in case register elimination gives us
1554 ;; the funny result.
1556 ;; ??? Maybe validate_changes should try adding match_scratch clobbers?
1558 ;; ??? Maybe we should change how adds are canonicalized.
1560 (define_insn "*madddi3"
1561 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1562 (plus:DI (mult:DI (match_operand:DI 1 "grfr_register_operand" "f")
1563 (match_operand:DI 2 "grfr_register_operand" "f"))
1564 (match_operand:DI 3 "grfr_register_operand" "f")))
1565 (clobber (match_scratch:DI 4 "=X"))]
1567 "xma.l %0 = %1, %2, %3%B0"
1568 [(set_attr "type" "F")])
1570 ;; This can be created by register elimination if operand3 of shladd is an
1571 ;; eliminable register or has reg_equiv_constant set.
1573 ;; We have to use nonmemory_operand for operand 4, to ensure that the
1574 ;; validate_changes call inside eliminate_regs will always succeed. If it
1575 ;; doesn't succeed, then this remain a madddi3 pattern, and will be reloaded
1578 (define_insn "*madddi3_elim"
1579 [(set (match_operand:DI 0 "register_operand" "=&r")
1580 (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "f")
1581 (match_operand:DI 2 "register_operand" "f"))
1582 (match_operand:DI 3 "register_operand" "f"))
1583 (match_operand:DI 4 "nonmemory_operand" "rI")))
1584 (clobber (match_scratch:DI 5 "=f"))]
1585 "reload_in_progress"
1587 [(set_attr "type" "unknown")])
1589 ;; ??? Need to emit an instruction group barrier here because this gets split
1593 [(set (match_operand:DI 0 "register_operand" "")
1594 (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
1595 (match_operand:DI 2 "register_operand" ""))
1596 (match_operand:DI 3 "register_operand" ""))
1597 (match_operand:DI 4 "gr_reg_or_14bit_operand" "")))
1598 (clobber (match_scratch:DI 5 ""))]
1600 [(parallel [(set (match_dup 5) (plus:DI (mult:DI (match_dup 1) (match_dup 2))
1602 (clobber (match_dup 0))])
1603 (unspec_volatile [(const_int 0)] 2)
1604 (set (match_dup 0) (match_dup 5))
1605 (unspec_volatile [(const_int 0)] 2)
1606 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
1609 ;; ??? There are highpart multiply and add instructions, but we have no way
1610 ;; to generate them.
1612 (define_insn "smuldi3_highpart"
1613 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1616 (mult:TI (sign_extend:TI
1617 (match_operand:DI 1 "fr_register_operand" "f"))
1619 (match_operand:DI 2 "fr_register_operand" "f")))
1622 "xma.h %0 = %1, %2, f0%B0"
1623 [(set_attr "type" "F")])
1625 (define_insn "umuldi3_highpart"
1626 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1629 (mult:TI (zero_extend:TI
1630 (match_operand:DI 1 "fr_register_operand" "f"))
1632 (match_operand:DI 2 "fr_register_operand" "f")))
1635 "xma.hu %0 = %1, %2, f0%B0"
1636 [(set_attr "type" "F")])
1638 (define_insn "negdi2"
1639 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1640 (neg:DI (match_operand:DI 1 "gr_register_operand" "r")))]
1643 [(set_attr "type" "A")])
1645 (define_expand "absdi2"
1647 (ge:CC (match_operand:DI 1 "gr_register_operand" "") (const_int 0)))
1648 (set (match_operand:DI 0 "gr_register_operand" "")
1649 (if_then_else:DI (eq:CC (match_dup 2) (const_int 0))
1650 (neg:DI (match_dup 1))
1655 operands[2] = gen_reg_rtx (CCmode);
1658 (define_expand "smindi3"
1660 (ge:CC (match_operand:DI 1 "gr_register_operand" "")
1661 (match_operand:DI 2 "gr_register_operand" "")))
1662 (set (match_operand:DI 0 "gr_register_operand" "")
1663 (if_then_else:DI (ne:CC (match_dup 3) (const_int 0))
1664 (match_dup 2) (match_dup 1)))]
1668 operands[3] = gen_reg_rtx (CCmode);
1671 (define_expand "smaxdi3"
1673 (ge:CC (match_operand:DI 1 "gr_register_operand" "")
1674 (match_operand:DI 2 "gr_register_operand" "")))
1675 (set (match_operand:DI 0 "gr_register_operand" "")
1676 (if_then_else:DI (ne:CC (match_dup 3) (const_int 0))
1677 (match_dup 1) (match_dup 2)))]
1681 operands[3] = gen_reg_rtx (CCmode);
1684 (define_expand "umindi3"
1686 (geu:CC (match_operand:DI 1 "gr_register_operand" "")
1687 (match_operand:DI 2 "gr_register_operand" "")))
1688 (set (match_operand:DI 0 "gr_register_operand" "")
1689 (if_then_else:DI (ne:CC (match_dup 3) (const_int 0))
1690 (match_dup 2) (match_dup 1)))]
1694 operands[3] = gen_reg_rtx (CCmode);
1697 (define_expand "umaxdi3"
1699 (geu:CC (match_operand:DI 1 "gr_register_operand" "")
1700 (match_operand:DI 2 "gr_register_operand" "")))
1701 (set (match_operand:DI 0 "gr_register_operand" "")
1702 (if_then_else:DI (ne:CC (match_dup 3) (const_int 0))
1703 (match_dup 1) (match_dup 2)))]
1707 operands[3] = gen_reg_rtx (CCmode);
1710 (define_expand "ffsdi2"
1712 (eq:CC (match_operand:DI 1 "gr_register_operand" "") (const_int 0)))
1713 (set (match_dup 2) (plus:DI (match_dup 1) (const_int -1)))
1714 (set (match_dup 5) (const_int 0))
1715 (set (match_dup 3) (xor:DI (match_dup 1) (match_dup 2)))
1716 (set (match_dup 4) (unspec:DI [(match_dup 3)] 8))
1717 (set (match_operand:DI 0 "gr_register_operand" "")
1718 (if_then_else:DI (ne:CC (match_dup 6) (const_int 0))
1719 (match_dup 5) (match_dup 4)))]
1723 operands[2] = gen_reg_rtx (DImode);
1724 operands[3] = gen_reg_rtx (DImode);
1725 operands[4] = gen_reg_rtx (DImode);
1726 operands[5] = gen_reg_rtx (DImode);
1727 operands[6] = gen_reg_rtx (CCmode);
1730 (define_insn "*popcnt"
1731 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1732 (unspec:DI [(match_operand:DI 1 "gr_register_operand" "r")] 8))]
1735 [(set_attr "type" "I")])
1738 ;; ::::::::::::::::::::
1740 ;; :: 32 bit floating point arithmetic
1742 ;; ::::::::::::::::::::
1744 (define_insn "addsf3"
1745 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1746 (plus:SF (match_operand:SF 1 "fr_register_operand" "%f")
1747 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
1749 "fadd.s %0 = %1, %F2%B0"
1750 [(set_attr "type" "F")])
1752 (define_insn "subsf3"
1753 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1754 (minus:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
1755 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
1757 "fsub.s %0 = %F1, %F2%B0"
1758 [(set_attr "type" "F")])
1760 (define_insn "mulsf3"
1761 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1762 (mult:SF (match_operand:SF 1 "fr_register_operand" "%f")
1763 (match_operand:SF 2 "fr_register_operand" "f")))]
1765 "fmpy.s %0 = %1, %2%B0"
1766 [(set_attr "type" "F")])
1768 (define_insn "abssf2"
1769 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1770 (abs:SF (match_operand:SF 1 "fr_register_operand" "f")))]
1773 [(set_attr "type" "F")])
1775 (define_insn "negsf2"
1776 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1777 (neg:SF (match_operand:SF 1 "fr_register_operand" "f")))]
1780 [(set_attr "type" "F")])
1782 (define_insn "*nabssf2"
1783 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1784 (neg:SF (abs:SF (match_operand:SF 1 "fr_register_operand" "f"))))]
1786 "fnegabs %0 = %1%B0"
1787 [(set_attr "type" "F")])
1789 (define_insn "minsf3"
1790 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1791 (smin:SF (match_operand:SF 1 "fr_register_operand" "f")
1792 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
1794 "fmin %0 = %1, %F2%B0"
1795 [(set_attr "type" "F")])
1797 (define_insn "maxsf3"
1798 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1799 (smax:SF (match_operand:SF 1 "fr_register_operand" "f")
1800 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
1802 "fmax %0 = %1, %F2%B0"
1803 [(set_attr "type" "F")])
1805 (define_insn "*maddsf3"
1806 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1807 (plus:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
1808 (match_operand:SF 2 "fr_register_operand" "f"))
1809 (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
1811 "fma.s %0 = %1, %2, %F3%B0"
1812 [(set_attr "type" "F")])
1814 (define_insn "*msubsf3"
1815 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1816 (minus:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
1817 (match_operand:SF 2 "fr_register_operand" "f"))
1818 (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
1820 "fms.s %0 = %1, %2, %F3%B0"
1821 [(set_attr "type" "F")])
1823 (define_insn "*nmulsf3"
1824 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1825 (neg:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
1826 (match_operand:SF 2 "fr_register_operand" "f"))))]
1828 "fnmpy.s %0 = %1, %2%B0"
1829 [(set_attr "type" "F")])
1831 ;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
1833 (define_insn "*nmaddsf3"
1834 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1835 (plus:SF (neg:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
1836 (match_operand:SF 2 "fr_register_operand" "f")))
1837 (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
1839 "fnma.s %0 = %1, %2, %F3%B0"
1840 [(set_attr "type" "F")])
1843 ;; ::::::::::::::::::::
1845 ;; :: 64 bit floating point arithmetic
1847 ;; ::::::::::::::::::::
1849 (define_insn "adddf3"
1850 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1851 (plus:DF (match_operand:DF 1 "fr_register_operand" "%f")
1852 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
1854 "fadd.d %0 = %1, %F2%B0"
1855 [(set_attr "type" "F")])
1857 (define_insn "subdf3"
1858 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1859 (minus:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
1860 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
1862 "fsub.d %0 = %F1, %F2%B0"
1863 [(set_attr "type" "F")])
1865 (define_insn "muldf3"
1866 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1867 (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
1868 (match_operand:DF 2 "fr_register_operand" "f")))]
1870 "fmpy.d %0 = %1, %2%B0"
1871 [(set_attr "type" "F")])
1873 (define_insn "absdf2"
1874 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1875 (abs:DF (match_operand:DF 1 "fr_register_operand" "f")))]
1878 [(set_attr "type" "F")])
1880 (define_insn "negdf2"
1881 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1882 (neg:DF (match_operand:DF 1 "fr_register_operand" "f")))]
1885 [(set_attr "type" "F")])
1887 (define_insn "*nabsdf2"
1888 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1889 (neg:DF (abs:DF (match_operand:DF 1 "fr_register_operand" "f"))))]
1891 "fnegabs %0 = %1%B0"
1892 [(set_attr "type" "F")])
1894 (define_insn "mindf3"
1895 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1896 (smin:DF (match_operand:DF 1 "fr_register_operand" "f")
1897 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
1899 "fmin %0 = %1, %F2%B0"
1900 [(set_attr "type" "F")])
1902 (define_insn "maxdf3"
1903 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1904 (smax:DF (match_operand:DF 1 "fr_register_operand" "f")
1905 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
1907 "fmax %0 = %1, %F2%B0"
1908 [(set_attr "type" "F")])
1910 (define_insn "*madddf3"
1911 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1912 (plus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
1913 (match_operand:DF 2 "fr_register_operand" "f"))
1914 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
1916 "fma.d %0 = %1, %2, %F3%B0"
1917 [(set_attr "type" "F")])
1919 (define_insn "*msubdf3"
1920 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1921 (minus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
1922 (match_operand:DF 2 "fr_register_operand" "f"))
1923 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
1925 "fms.d %0 = %1, %2, %F3%B0"
1926 [(set_attr "type" "F")])
1928 (define_insn "*nmuldf3"
1929 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1930 (neg:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
1931 (match_operand:DF 2 "fr_register_operand" "f"))))]
1933 "fnmpy.d %0 = %1, %2%B0"
1934 [(set_attr "type" "F")])
1936 ;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
1938 (define_insn "*nmadddf3"
1939 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1940 (plus:DF (neg:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
1941 (match_operand:DF 2 "fr_register_operand" "f")))
1942 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
1944 "fnma.d %0 = %1, %2, %F3%B0"
1945 [(set_attr "type" "F")])
1947 ;; ::::::::::::::::::::
1949 ;; :: 80 bit floating point arithmetic
1951 ;; ::::::::::::::::::::
1953 (define_insn "addtf3"
1954 [(set (match_operand:TF 0 "fr_register_operand" "=f")
1955 (plus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
1956 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
1958 "fadd %0 = %F1, %F2%B0"
1959 [(set_attr "type" "F")])
1961 (define_insn "subtf3"
1962 [(set (match_operand:TF 0 "fr_register_operand" "=f")
1963 (minus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
1964 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
1966 "fsub %0 = %F1, %F2%B0"
1967 [(set_attr "type" "F")])
1969 (define_insn "multf3"
1970 [(set (match_operand:TF 0 "fr_register_operand" "=f")
1971 (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
1972 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
1974 "fmpy %0 = %F1, %F2%B0"
1975 [(set_attr "type" "F")])
1977 (define_insn "abstf2"
1978 [(set (match_operand:TF 0 "fr_register_operand" "=f")
1979 (abs:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")))]
1982 [(set_attr "type" "F")])
1984 (define_insn "negtf2"
1985 [(set (match_operand:TF 0 "fr_register_operand" "=f")
1986 (neg:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")))]
1989 [(set_attr "type" "F")])
1991 (define_insn "*nabstf2"
1992 [(set (match_operand:TF 0 "fr_register_operand" "=f")
1993 (neg:TF (abs:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG"))))]
1995 "fnegabs %0 = %F1%B0"
1996 [(set_attr "type" "F")])
1998 (define_insn "mintf3"
1999 [(set (match_operand:TF 0 "fr_register_operand" "=f")
2000 (smin:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
2001 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
2003 "fmin %0 = %F1, %F2%B0"
2004 [(set_attr "type" "F")])
2006 (define_insn "maxtf3"
2007 [(set (match_operand:TF 0 "fr_register_operand" "=f")
2008 (smax:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
2009 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
2011 "fmax %0 = %F1, %F2%B0"
2012 [(set_attr "type" "F")])
2014 (define_insn "*maddtf3"
2015 [(set (match_operand:TF 0 "fr_register_operand" "=f")
2016 (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
2017 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
2018 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))]
2020 "fma %0 = %F1, %F2, %F3%B0"
2021 [(set_attr "type" "F")])
2023 (define_insn "*msubtf3"
2024 [(set (match_operand:TF 0 "fr_register_operand" "=f")
2025 (minus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
2026 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
2027 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))]
2029 "fms %0 = %F1, %F2, %F3%B0"
2030 [(set_attr "type" "F")])
2032 (define_insn "*nmultf3"
2033 [(set (match_operand:TF 0 "fr_register_operand" "=f")
2034 (neg:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
2035 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
2037 "fnmpy %0 = %F1, %F2%B0"
2038 [(set_attr "type" "F")])
2040 ;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
2042 (define_insn "*nmaddtf3"
2043 [(set (match_operand:TF 0 "fr_register_operand" "=f")
2044 (plus:TF (neg:TF (mult:TF
2045 (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
2046 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
2047 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))]
2049 "fnma %0 = %F1, %F2, %F3%B0"
2050 [(set_attr "type" "F")])
2052 ;; ::::::::::::::::::::
2054 ;; :: 32 bit Integer Shifts and Rotates
2056 ;; ::::::::::::::::::::
2058 (define_expand "ashlsi3"
2059 [(set (match_operand:SI 0 "gr_register_operand" "")
2060 (ashift:SI (match_operand:SI 1 "gr_register_operand" "")
2061 (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
2065 if (GET_CODE (operands[2]) != CONST_INT)
2067 /* Why oh why didn't Intel arrange for SHIFT_COUNT_TRUNCATED? Now
2068 we've got to get rid of stray bits outside the SImode register. */
2069 rtx subshift = gen_reg_rtx (DImode);
2070 emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
2071 operands[2] = subshift;
2075 (define_insn "*ashlsi3_internal"
2076 [(set (match_operand:SI 0 "gr_register_operand" "=r,r,r")
2077 (ashift:SI (match_operand:SI 1 "gr_register_operand" "r,r,r")
2078 (match_operand:DI 2 "gr_reg_or_5bit_operand" "R,n,r")))]
2081 shladd %0 = %1, %2, r0
2082 dep.z %0 = %1, %2, %E2
2084 [(set_attr "type" "A,I,I")])
2086 (define_expand "ashrsi3"
2087 [(set (match_operand:SI 0 "gr_register_operand" "")
2088 (ashiftrt:SI (match_operand:SI 1 "gr_register_operand" "")
2089 (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
2093 rtx subtarget = gen_reg_rtx (DImode);
2094 if (GET_CODE (operands[2]) == CONST_INT)
2095 emit_insn (gen_extv (subtarget, gen_lowpart (DImode, operands[1]),
2096 GEN_INT (32 - INTVAL (operands[2])), operands[2]));
2099 rtx subshift = gen_reg_rtx (DImode);
2100 emit_insn (gen_extendsidi2 (subtarget, operands[1]));
2101 emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
2102 emit_insn (gen_ashrdi3 (subtarget, subtarget, subshift));
2104 emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget);
2108 (define_expand "lshrsi3"
2109 [(set (match_operand:SI 0 "gr_register_operand" "")
2110 (lshiftrt:SI (match_operand:SI 1 "gr_register_operand" "")
2111 (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
2115 rtx subtarget = gen_reg_rtx (DImode);
2116 if (GET_CODE (operands[2]) == CONST_INT)
2117 emit_insn (gen_extzv (subtarget, gen_lowpart (DImode, operands[1]),
2118 GEN_INT (32 - INTVAL (operands[2])), operands[2]));
2121 rtx subshift = gen_reg_rtx (DImode);
2122 emit_insn (gen_zero_extendsidi2 (subtarget, operands[1]));
2123 emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
2124 emit_insn (gen_lshrdi3 (subtarget, subtarget, subshift));
2126 emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget);
2130 ;; Use mix4.r/shr to implement rotrsi3. We only get 32 bits of valid result
2131 ;; here, instead of 64 like the patterns above.
2133 (define_expand "rotrsi3"
2135 (ior:DI (zero_extend:DI (match_operand:SI 1 "gr_register_operand" ""))
2136 (ashift:DI (zero_extend:DI (match_dup 1)) (const_int 32))))
2138 (lshiftrt:DI (match_dup 3)
2139 (match_operand:DI 2 "nonmemory_operand" "")))
2140 (set (match_operand:SI 0 "gr_register_operand" "") (match_dup 4))]
2144 if (! shift_32bit_count_operand (operands[2], SImode))
2146 operands[3] = gen_reg_rtx (DImode);
2147 operands[4] = gen_lowpart (SImode, operands[3]);
2150 ;; ::::::::::::::::::::
2152 ;; :: 64 bit Integer Shifts and Rotates
2154 ;; ::::::::::::::::::::
2156 (define_insn "ashldi3"
2157 [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
2158 (ashift:DI (match_operand:DI 1 "gr_register_operand" "r,r")
2159 (match_operand:DI 2 "gr_reg_or_6bit_operand" "R,rM")))]
2162 shladd %0 = %1, %2, r0
2164 [(set_attr "type" "A,I")])
2166 ;; ??? Maybe combine this with the multiply and add instruction?
2168 (define_insn "*shladd"
2169 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2170 (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
2171 (match_operand:DI 2 "shladd_operand" "n"))
2172 (match_operand:DI 3 "gr_register_operand" "r")))]
2174 "shladd %0 = %1, %S2, %3"
2175 [(set_attr "type" "A")])
2177 ;; This can be created by register elimination if operand3 of shladd is an
2178 ;; eliminable register or has reg_equiv_constant set.
2180 ;; We have to use nonmemory_operand for operand 4, to ensure that the
2181 ;; validate_changes call inside eliminate_regs will always succeed. If it
2182 ;; doesn't succeed, then this remain a shladd pattern, and will be reloaded
2185 (define_insn_and_split "*shladd_elim"
2186 [(set (match_operand:DI 0 "gr_register_operand" "=&r")
2187 (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
2188 (match_operand:DI 2 "shladd_operand" "n"))
2189 (match_operand:DI 3 "nonmemory_operand" "r"))
2190 (match_operand:DI 4 "nonmemory_operand" "rI")))]
2191 "reload_in_progress"
2194 [(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (match_dup 2))
2196 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
2198 [(set_attr "type" "unknown")])
2200 (define_insn "ashrdi3"
2201 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2202 (ashiftrt:DI (match_operand:DI 1 "gr_register_operand" "r")
2203 (match_operand:DI 2 "gr_reg_or_6bit_operand" "rM")))]
2206 [(set_attr "type" "I")])
2208 (define_insn "lshrdi3"
2209 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2210 (lshiftrt:DI (match_operand:DI 1 "gr_register_operand" "r")
2211 (match_operand:DI 2 "gr_reg_or_6bit_operand" "rM")))]
2214 [(set_attr "type" "I")])
2216 ;; Using a predicate that accepts only constants doesn't work, because optabs
2217 ;; will load the operand into a register and call the pattern if the predicate
2218 ;; did not accept it on the first try. So we use nonmemory_operand and then
2219 ;; verify that we have an appropriate constant in the expander.
2221 (define_expand "rotrdi3"
2222 [(set (match_operand:DI 0 "gr_register_operand" "")
2223 (rotatert:DI (match_operand:DI 1 "gr_register_operand" "")
2224 (match_operand:DI 2 "nonmemory_operand" "")))]
2228 if (! shift_count_operand (operands[2], DImode))
2232 (define_insn "*rotrdi3_internal"
2233 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2234 (rotatert:DI (match_operand:DI 1 "gr_register_operand" "r")
2235 (match_operand:DI 2 "shift_count_operand" "M")))]
2237 "shrp %0 = %1, %1, %2"
2238 [(set_attr "type" "I")])
2241 ;; ::::::::::::::::::::
2243 ;; :: 32 bit Integer Logical operations
2245 ;; ::::::::::::::::::::
2247 ;; We don't seem to need any other 32-bit logical operations, because gcc
2248 ;; generates zero-extend;zero-extend;DImode-op, which combine optimizes to
2249 ;; DImode-op;zero-extend, and then we can optimize away the zero-extend.
2250 ;; This doesn't work for unary logical operations, because we don't call
2251 ;; apply_distributive_law for them.
2253 ;; ??? Likewise, this doesn't work for andnot, which isn't handled by
2254 ;; apply_distributive_law. We get inefficient code for
2255 ;; int sub4 (int i, int j) { return i & ~j; }
2256 ;; We could convert (and (not (sign_extend A)) (sign_extend B)) to
2257 ;; (zero_extend (and (not A) B)) in combine.
2258 ;; Or maybe fix this by adding andsi3/iorsi3/xorsi3 patterns like the
2259 ;; one_cmplsi2 pattern.
2261 (define_insn "one_cmplsi2"
2262 [(set (match_operand:SI 0 "gr_register_operand" "=r")
2263 (not:SI (match_operand:SI 1 "gr_register_operand" "r")))]
2266 [(set_attr "type" "A")])
2268 ;; ::::::::::::::::::::
2270 ;; :: 64 bit Integer Logical operations
2272 ;; ::::::::::::::::::::
2274 (define_insn "anddi3"
2275 [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
2276 (and:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
2277 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
2281 fand %0 = %2, %1%B0"
2282 [(set_attr "type" "A,F")])
2284 (define_insn "*andnot"
2285 [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
2286 (and:DI (not:DI (match_operand:DI 1 "grfr_register_operand" "r,*f"))
2287 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
2291 fandcm %0 = %2, %1%B0"
2292 [(set_attr "type" "A,F")])
2294 (define_insn "iordi3"
2295 [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
2296 (ior:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
2297 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
2302 [(set_attr "type" "A,F")])
2304 (define_insn "xordi3"
2305 [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
2306 (xor:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
2307 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
2311 fxor %0 = %2, %1%B0"
2312 [(set_attr "type" "A,F")])
2314 (define_insn "one_cmpldi2"
2315 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2316 (not:DI (match_operand:DI 1 "gr_register_operand" "r")))]
2319 [(set_attr "type" "A")])
2321 ;; ::::::::::::::::::::
2325 ;; ::::::::::::::::::::
2327 (define_expand "cmpsi"
2329 (compare (match_operand:SI 0 "gr_register_operand" "")
2330 (match_operand:SI 1 "gr_reg_or_8bit_and_adjusted_operand" "")))]
2334 ia64_compare_op0 = operands[0];
2335 ia64_compare_op1 = operands[1];
2339 (define_expand "cmpdi"
2341 (compare (match_operand:DI 0 "gr_register_operand" "")
2342 (match_operand:DI 1 "gr_reg_or_8bit_and_adjusted_operand" "")))]
2346 ia64_compare_op0 = operands[0];
2347 ia64_compare_op1 = operands[1];
2351 (define_expand "cmpsf"
2353 (compare (match_operand:SF 0 "fr_reg_or_fp01_operand" "")
2354 (match_operand:SF 1 "fr_reg_or_fp01_operand" "")))]
2358 ia64_compare_op0 = operands[0];
2359 ia64_compare_op1 = operands[1];
2363 (define_expand "cmpdf"
2365 (compare (match_operand:DF 0 "fr_reg_or_fp01_operand" "")
2366 (match_operand:DF 1 "fr_reg_or_fp01_operand" "")))]
2370 ia64_compare_op0 = operands[0];
2371 ia64_compare_op1 = operands[1];
2375 (define_expand "cmptf"
2377 (compare (match_operand:TF 0 "tfreg_or_fp01_operand" "")
2378 (match_operand:TF 1 "tfreg_or_fp01_operand" "")))]
2382 ia64_compare_op0 = operands[0];
2383 ia64_compare_op1 = operands[1];
2387 (define_insn "*cmpsi_normal"
2388 [(set (match_operand:CC 0 "register_operand" "=c")
2389 (match_operator:CC 1 "normal_comparison_operator"
2390 [(match_operand:SI 2 "gr_register_operand" "r")
2391 (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))]
2393 "cmp4.%C1 %0, %I0 = %3, %2"
2394 [(set_attr "type" "A")])
2396 (define_insn "*cmpsi_adjusted"
2397 [(set (match_operand:CC 0 "register_operand" "=c")
2398 (match_operator:CC 1 "adjusted_comparison_operator"
2399 [(match_operand:SI 2 "gr_register_operand" "r")
2400 (match_operand:SI 3 "gr_reg_or_8bit_adjusted_operand" "rL")]))]
2402 "cmp4.%C1 %0, %I0 = %3, %2"
2403 [(set_attr "type" "A")])
2405 (define_insn "*cmpdi_normal"
2406 [(set (match_operand:CC 0 "register_operand" "=c")
2407 (match_operator:CC 1 "normal_comparison_operator"
2408 [(match_operand:DI 2 "gr_register_operand" "r")
2409 (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))]
2411 "cmp.%C1 %0, %I0 = %3, %2"
2412 [(set_attr "type" "A")])
2414 (define_insn "*cmpdi_adjusted"
2415 [(set (match_operand:CC 0 "register_operand" "=c")
2416 (match_operator:CC 1 "adjusted_comparison_operator"
2417 [(match_operand:DI 2 "gr_register_operand" "r")
2418 (match_operand:DI 3 "gr_reg_or_8bit_adjusted_operand" "rL")]))]
2420 "cmp.%C1 %0, %I0 = %3, %2"
2421 [(set_attr "type" "A")])
2423 (define_insn "*cmpsf_internal"
2424 [(set (match_operand:CC 0 "register_operand" "=c")
2425 (match_operator:CC 1 "comparison_operator"
2426 [(match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")
2427 (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")]))]
2429 "fcmp.%D1 %0, %I0 = %F2, %F3"
2430 [(set_attr "type" "F")])
2432 (define_insn "*cmpdf_internal"
2433 [(set (match_operand:CC 0 "register_operand" "=c")
2434 (match_operator:CC 1 "comparison_operator"
2435 [(match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")
2436 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")]))]
2438 "fcmp.%D1 %0, %I0 = %F2, %F3"
2439 [(set_attr "type" "F")])
2441 (define_insn "*cmptf_internal"
2442 [(set (match_operand:CC 0 "register_operand" "=c")
2443 (match_operator:CC 1 "comparison_operator"
2444 [(match_operand:TF 2 "tfreg_or_fp01_operand" "fG")
2445 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")]))]
2447 "fcmp.%D1 %0, %I0 = %F2, %F3"
2448 [(set_attr "type" "F")])
2450 ;; ??? Can this pattern be generated?
2452 (define_insn "*bit_zero"
2453 [(set (match_operand:CC 0 "register_operand" "=c")
2454 (eq:CC (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
2456 (match_operand:DI 2 "immediate_operand" "n"))
2459 "tbit.z %0, %I0 = %1, %2"
2460 [(set_attr "type" "I")])
2462 (define_insn "*bit_one"
2463 [(set (match_operand:CC 0 "register_operand" "=c")
2464 (ne:CC (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
2466 (match_operand:DI 2 "immediate_operand" "n"))
2469 "tbit.nz %0, %I0 = %1, %2"
2470 [(set_attr "type" "I")])
2472 ;; ??? We also need this if we run out of PR regs and need to spill some.
2474 ;; ??? We need this if a CCmode value does not get allocated to a hard
2475 ;; register. This happens if we cse/gcse a CCmode value across a call, and the
2476 ;; function has a nonlocal goto. This is because global does not allocate
2477 ;; call crossing pseudos to hard registers when current_function_has_
2478 ;; nonlocal_goto is true. This is relatively common for C++ programs that
2479 ;; use exceptions. See ia64_secondary_reload_class.
2481 ;; We use a define_expand here so that cse/gcse/combine can't accidentally
2482 ;; create movcc insns. If this was a named define_insn, we would not be able
2483 ;; to make it conditional on reload.
2485 (define_expand "movcc"
2486 [(set (match_operand:CC 0 "nonimmediate_operand" "")
2487 (match_operand:CC 1 "move_operand" ""))]
2491 if (! reload_in_progress && ! reload_completed)
2495 (define_insn "*movcc_internal"
2496 [(set (match_operand:CC 0 "nonimmediate_operand" "=r,c,r,m")
2497 (match_operand:CC 1 "move_operand" "c,r,m,r"))]
2498 "reload_in_progress || reload_completed"
2501 cmp4.ne %0, %I0 = %1, r0
2504 [(set_attr "type" "unknown,A,M,M")])
2507 [(set (match_operand:CC 0 "register_operand" "")
2508 (match_operand:CC 1 "register_operand" ""))]
2510 && GET_CODE (operands[0]) == REG && GR_REGNO_P (REGNO (operands[0]))
2511 && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
2513 (if_then_else:DI (ne:CC (match_dup 1) (const_int 0))
2517 (if_then_else:DI (ne:CC (match_dup 1) (const_int 0))
2520 "operands[2] = gen_rtx_SUBREG (DImode, operands[0], 0);")
2523 ;; ::::::::::::::::::::
2527 ;; ::::::::::::::::::::
2529 (define_expand "beq"
2531 (eq:CC (match_dup 2)
2534 (if_then_else (ne:CC (match_dup 1)
2536 (label_ref (match_operand 0 "" ""))
2541 operands[1] = gen_reg_rtx (CCmode);
2542 operands[2] = ia64_compare_op0;
2543 operands[3] = ia64_compare_op1;
2546 (define_expand "bne"
2548 (ne:CC (match_dup 2)
2551 (if_then_else (ne:CC (match_dup 1)
2553 (label_ref (match_operand 0 "" ""))
2558 operands[1] = gen_reg_rtx (CCmode);
2559 operands[2] = ia64_compare_op0;
2560 operands[3] = ia64_compare_op1;
2563 (define_expand "blt"
2565 (lt:CC (match_dup 2)
2568 (if_then_else (ne:CC (match_dup 1)
2570 (label_ref (match_operand 0 "" ""))
2575 operands[1] = gen_reg_rtx (CCmode);
2576 operands[2] = ia64_compare_op0;
2577 operands[3] = ia64_compare_op1;
2580 (define_expand "ble"
2582 (le:CC (match_dup 2)
2585 (if_then_else (ne:CC (match_dup 1)
2587 (label_ref (match_operand 0 "" ""))
2592 operands[1] = gen_reg_rtx (CCmode);
2593 operands[2] = ia64_compare_op0;
2594 operands[3] = ia64_compare_op1;
2597 (define_expand "bgt"
2599 (gt:CC (match_dup 2)
2602 (if_then_else (ne:CC (match_dup 1)
2604 (label_ref (match_operand 0 "" ""))
2609 operands[1] = gen_reg_rtx (CCmode);
2610 operands[2] = ia64_compare_op0;
2611 operands[3] = ia64_compare_op1;
2614 (define_expand "bge"
2616 (ge:CC (match_dup 2)
2619 (if_then_else (ne:CC (match_dup 1)
2621 (label_ref (match_operand 0 "" ""))
2626 operands[1] = gen_reg_rtx (CCmode);
2627 operands[2] = ia64_compare_op0;
2628 operands[3] = ia64_compare_op1;
2631 (define_expand "bltu"
2633 (ltu:CC (match_dup 2)
2636 (if_then_else (ne:CC (match_dup 1)
2638 (label_ref (match_operand 0 "" ""))
2643 operands[1] = gen_reg_rtx (CCmode);
2644 operands[2] = ia64_compare_op0;
2645 operands[3] = ia64_compare_op1;
2648 (define_expand "bleu"
2650 (leu:CC (match_dup 2)
2653 (if_then_else (ne:CC (match_dup 1)
2655 (label_ref (match_operand 0 "" ""))
2660 operands[1] = gen_reg_rtx (CCmode);
2661 operands[2] = ia64_compare_op0;
2662 operands[3] = ia64_compare_op1;
2665 (define_expand "bgtu"
2667 (gtu:CC (match_dup 2)
2670 (if_then_else (ne:CC (match_dup 1)
2672 (label_ref (match_operand 0 "" ""))
2677 operands[1] = gen_reg_rtx (CCmode);
2678 operands[2] = ia64_compare_op0;
2679 operands[3] = ia64_compare_op1;
2682 (define_expand "bgeu"
2684 (geu:CC (match_dup 2)
2687 (if_then_else (ne:CC (match_dup 1)
2689 (label_ref (match_operand 0 "" ""))
2694 operands[1] = gen_reg_rtx (CCmode);
2695 operands[2] = ia64_compare_op0;
2696 operands[3] = ia64_compare_op1;
2699 (define_expand "bunordered"
2701 (unordered:CC (match_dup 2)
2704 (if_then_else (ne:CC (match_dup 1)
2706 (label_ref (match_operand 0 "" ""))
2711 operands[1] = gen_reg_rtx (CCmode);
2712 operands[2] = ia64_compare_op0;
2713 operands[3] = ia64_compare_op1;
2716 (define_expand "bordered"
2718 (ordered:CC (match_dup 2)
2721 (if_then_else (ne:CC (match_dup 1)
2723 (label_ref (match_operand 0 "" ""))
2728 operands[1] = gen_reg_rtx (CCmode);
2729 operands[2] = ia64_compare_op0;
2730 operands[3] = ia64_compare_op1;
2733 (define_insn "*br_true"
2735 (if_then_else (match_operator 0 "predicate_operator"
2736 [(match_operand:CC 1 "register_operand" "c")
2738 (label_ref (match_operand 2 "" ""))
2741 "(%J0) br.cond%+ %l2"
2742 [(set_attr "type" "B")
2743 (set_attr "predicable" "no")])
2745 (define_insn "*br_false"
2747 (if_then_else (match_operator 0 "predicate_operator"
2748 [(match_operand:CC 1 "register_operand" "c")
2751 (label_ref (match_operand 2 "" ""))))]
2753 "(%j0) br.cond%+ %l2"
2754 [(set_attr "type" "B")
2755 (set_attr "predicable" "no")])
2757 ;; ::::::::::::::::::::
2759 ;; :: Counted loop operations
2761 ;; ::::::::::::::::::::
2763 (define_expand "doloop_end"
2764 [(use (match_operand 0 "" "")) ; loop pseudo
2765 (use (match_operand 1 "" "")) ; iterations; zero if unknown
2766 (use (match_operand 2 "" "")) ; max iterations
2767 (use (match_operand 3 "" "")) ; loop level
2768 (use (match_operand 4 "" ""))] ; label
2772 /* Only use cloop on innermost loops. */
2773 if (INTVAL (operands[3]) > 1)
2775 emit_jump_insn (gen_doloop_end_internal (gen_rtx_REG (DImode, AR_LC_REGNUM),
2780 (define_insn "doloop_end_internal"
2781 [(set (pc) (if_then_else (ne (match_operand:DI 0 "ar_lc_reg_operand" "")
2783 (label_ref (match_operand 1 "" ""))
2785 (set (match_dup 0) (if_then_else:DI (ne (match_dup 0) (const_int 0))
2787 (plus:DI (match_dup 0) (const_int -1))))]
2789 "br.cloop.sptk.few %l1"
2790 [(set_attr "type" "B")
2791 (set_attr "predicable" "no")])
2793 ;; ::::::::::::::::::::
2795 ;; :: Set flag operations
2797 ;; ::::::::::::::::::::
2799 (define_expand "seq"
2801 (eq:CC (match_dup 2)
2803 (set (match_operand:DI 0 "gr_register_operand" "")
2804 (ne:DI (match_dup 1) (const_int 0)))]
2808 operands[1] = gen_reg_rtx (CCmode);
2809 operands[2] = ia64_compare_op0;
2810 operands[3] = ia64_compare_op1;
2813 (define_expand "sne"
2815 (ne:CC (match_dup 2)
2817 (set (match_operand:DI 0 "gr_register_operand" "")
2818 (ne:DI (match_dup 1) (const_int 0)))]
2822 operands[1] = gen_reg_rtx (CCmode);
2823 operands[2] = ia64_compare_op0;
2824 operands[3] = ia64_compare_op1;
2827 (define_expand "slt"
2829 (lt:CC (match_dup 2)
2831 (set (match_operand:DI 0 "gr_register_operand" "")
2832 (ne:DI (match_dup 1) (const_int 0)))]
2836 operands[1] = gen_reg_rtx (CCmode);
2837 operands[2] = ia64_compare_op0;
2838 operands[3] = ia64_compare_op1;
2841 (define_expand "sle"
2843 (le:CC (match_dup 2)
2845 (set (match_operand:DI 0 "gr_register_operand" "")
2846 (ne:DI (match_dup 1) (const_int 0)))]
2850 operands[1] = gen_reg_rtx (CCmode);
2851 operands[2] = ia64_compare_op0;
2852 operands[3] = ia64_compare_op1;
2855 (define_expand "sgt"
2857 (gt:CC (match_dup 2)
2859 (set (match_operand:DI 0 "gr_register_operand" "")
2860 (ne:DI (match_dup 1) (const_int 0)))]
2864 operands[1] = gen_reg_rtx (CCmode);
2865 operands[2] = ia64_compare_op0;
2866 operands[3] = ia64_compare_op1;
2869 (define_expand "sge"
2871 (ge:CC (match_dup 2)
2873 (set (match_operand:DI 0 "gr_register_operand" "")
2874 (ne:DI (match_dup 1) (const_int 0)))]
2878 operands[1] = gen_reg_rtx (CCmode);
2879 operands[2] = ia64_compare_op0;
2880 operands[3] = ia64_compare_op1;
2883 (define_expand "sltu"
2885 (ltu:CC (match_dup 2)
2887 (set (match_operand:DI 0 "gr_register_operand" "")
2888 (ne:DI (match_dup 1) (const_int 0)))]
2892 operands[1] = gen_reg_rtx (CCmode);
2893 operands[2] = ia64_compare_op0;
2894 operands[3] = ia64_compare_op1;
2897 (define_expand "sleu"
2899 (leu:CC (match_dup 2)
2901 (set (match_operand:DI 0 "gr_register_operand" "")
2902 (ne:DI (match_dup 1) (const_int 0)))]
2906 operands[1] = gen_reg_rtx (CCmode);
2907 operands[2] = ia64_compare_op0;
2908 operands[3] = ia64_compare_op1;
2911 (define_expand "sgtu"
2913 (gtu:CC (match_dup 2)
2915 (set (match_operand:DI 0 "gr_register_operand" "")
2916 (ne:DI (match_dup 1) (const_int 0)))]
2920 operands[1] = gen_reg_rtx (CCmode);
2921 operands[2] = ia64_compare_op0;
2922 operands[3] = ia64_compare_op1;
2925 (define_expand "sgeu"
2927 (geu:CC (match_dup 2)
2929 (set (match_operand:DI 0 "gr_register_operand" "")
2930 (ne:DI (match_dup 1) (const_int 0)))]
2934 operands[1] = gen_reg_rtx (CCmode);
2935 operands[2] = ia64_compare_op0;
2936 operands[3] = ia64_compare_op1;
2939 (define_expand "sunordered"
2941 (unordered:CC (match_dup 2)
2943 (set (match_operand:DI 0 "gr_register_operand" "")
2944 (ne:DI (match_dup 1) (const_int 0)))]
2948 operands[1] = gen_reg_rtx (CCmode);
2949 operands[2] = ia64_compare_op0;
2950 operands[3] = ia64_compare_op1;
2953 (define_expand "sordered"
2955 (ordered:CC (match_dup 2)
2957 (set (match_operand:DI 0 "gr_register_operand" "")
2958 (ne:DI (match_dup 1) (const_int 0)))]
2962 operands[1] = gen_reg_rtx (CCmode);
2963 operands[2] = ia64_compare_op0;
2964 operands[3] = ia64_compare_op1;
2967 ;; Don't allow memory as destination here, because cmov/cmov/st is more
2968 ;; efficient than mov/mov/cst/cst.
2970 (define_insn_and_split "*sne_internal"
2971 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2972 (ne:DI (match_operand:CC 1 "register_operand" "c")
2978 (if_then_else:DI (ne:CC (match_dup 1) (const_int 0))
2982 (if_then_else:DI (ne:CC (match_dup 1) (const_int 0))
2986 [(set_attr "type" "unknown")])
2988 ;; ??? Unknown if this can be matched.
2990 (define_insn_and_split "*seq_internal"
2991 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2992 (eq:DI (match_operand:CC 1 "register_operand" "c")
2998 (if_then_else:DI (eq:CC (match_dup 1) (const_int 0))
3002 (if_then_else:DI (eq:CC (match_dup 1) (const_int 0))
3006 [(set_attr "type" "unknown")])
3009 ;; ::::::::::::::::::::
3011 ;; :: Conditional move instructions.
3013 ;; ::::::::::::::::::::
3015 ;; ??? Add movXXcc patterns?
3018 ;; DImode if_then_else patterns.
3021 ;; Errata 72 workaround.
3022 (define_insn "*cmovdi_internal_astep"
3023 [(set (match_operand:DI 0 "nonimmediate_operand"
3024 "=r,*f,Q,*b,r,*f,Q,*b,r,*f,Q,*b")
3026 (match_operator:CC 4 "predicate_operator"
3027 [(match_operand:CC 1 "register_operand"
3028 "c,c,c,c,c,c,c,c,c,c,c,c")
3030 (match_operand:DI 2 "general_operand"
3031 "0,0,0,0,ri*f*b,rO,*f,r,ri*f*b,rO,*f,r")
3032 (match_operand:DI 3 "general_operand"
3033 "ri*f*b,rO,*f,r,0,0,0,0,ri*f*b,rO,*f,r")))]
3036 [(set_attr "predicable" "no")])
3038 (define_insn "*cmovdi_internal"
3039 [(set (match_operand:DI 0 "nonimmediate_operand"
3040 "=r,m,*f,Q,*b,*d*e,r,m,*f,Q,*b,*d*e,r,m,*f,Q,*b,*d*e")
3042 (match_operator:CC 4 "predicate_operator"
3043 [(match_operand:CC 1 "register_operand"
3044 "c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c")
3046 (match_operand:DI 2 "general_operand"
3047 "0,0,0,0,0,0,rim*f*b*d*e,rO,rOQ,*f,rO,rK,rim*f*b*d*e,rO,rOQ,*f,rO,rK")
3048 (match_operand:DI 3 "general_operand"
3049 "rim*f*b*d*e,rO,rOQ,*f,rO,rK,0,0,0,0,0,0,rim*f*b*d*e,rO,rOQ,*f,rO,rK")))]
3052 [(set_attr "predicable" "no")])
3055 [(set (match_operand 0 "nonimmediate_operand" "")
3057 (match_operator:CC 4 "predicate_operator"
3058 [(match_operand:CC 1 "register_operand" "")
3060 (match_operand 2 "general_operand" "")
3061 (match_operand 3 "general_operand" "")))]
3067 if (! rtx_equal_p (operands[0], operands[2]))
3069 tmp = gen_rtx_SET (VOIDmode, operands[0], operands[2]);
3070 tmp = gen_rtx_COND_EXEC (VOIDmode, operands[4], tmp);
3073 if (! rtx_equal_p (operands[0], operands[3]))
3075 tmp = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
3076 CCmode, operands[1], const0_rtx);
3077 tmp = gen_rtx_COND_EXEC (VOIDmode, tmp,
3078 gen_rtx_SET (VOIDmode, operands[0],
3085 ;; Absolute value pattern.
3087 (define_insn "*absdi2_internal"
3088 [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
3090 (match_operator:CC 4 "predicate_operator"
3091 [(match_operand:CC 1 "register_operand" "c,c")
3093 (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" "rI,rI"))
3094 (match_operand:DI 3 "gr_reg_or_22bit_operand" "0,rI")))]
3097 [(set_attr "type" "A,unknown")
3098 (set_attr "predicable" "no")])
3101 [(set (match_operand:DI 0 "register_operand" "")
3103 (match_operator:CC 4 "predicate_operator"
3104 [(match_operand:CC 1 "register_operand" "c,c")
3106 (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" ""))
3107 (match_operand:DI 3 "gr_reg_or_22bit_operand" "")))]
3108 "reload_completed && rtx_equal_p (operands[0], operands[3])"
3112 (neg:DI (match_dup 2))))]
3116 [(set (match_operand:DI 0 "register_operand" "")
3118 (match_operator:CC 4 "predicate_operator"
3119 [(match_operand:CC 1 "register_operand" "c,c")
3121 (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" ""))
3122 (match_operand:DI 3 "gr_reg_or_22bit_operand" "")))]
3126 (set (match_dup 0) (neg:DI (match_dup 2))))
3129 (set (match_dup 0) (match_dup 3)))]
3132 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
3133 CCmode, operands[1], const0_rtx);
3137 ;; SImode if_then_else patterns.
3140 (define_insn "*cmovsi_internal_astep"
3141 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,*f,r,*f,r,*f")
3143 (match_operator:CC 4 "predicate_operator"
3144 [(match_operand:CC 1 "register_operand" "c,c,c,c,c,c")
3146 (match_operand:SI 2 "general_operand"
3147 "0,0,ri*f,rO,ri*f,rO")
3148 (match_operand:SI 3 "general_operand"
3149 "ri*f,rO,0,0,ri*f,rO")))]
3152 [(set_attr "predicable" "no")])
3154 (define_insn "*cmovsi_internal"
3155 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,*f,r,m,*f,r,m,*f")
3157 (match_operator:CC 4 "predicate_operator"
3158 [(match_operand:CC 1 "register_operand" "c,c,c,c,c,c,c,c,c")
3160 (match_operand:SI 2 "general_operand"
3161 "0,0,0,rim*f,rO,rO,rim*f,rO,rO")
3162 (match_operand:SI 3 "general_operand"
3163 "rim*f,rO,rO,0,0,0,rim*f,rO,rO")))]
3166 [(set_attr "predicable" "no")])
3168 (define_insn "*abssi2_internal"
3169 [(set (match_operand:SI 0 "gr_register_operand" "=r,r")
3171 (match_operator:CC 4 "predicate_operator"
3172 [(match_operand:CC 1 "register_operand" "c,c")
3174 (neg:SI (match_operand:SI 3 "gr_reg_or_22bit_operand" "rI,rI"))
3175 (match_operand:SI 2 "gr_reg_or_22bit_operand" "0,rI")))]
3178 [(set_attr "type" "A,unknown")
3179 (set_attr "predicable" "no")])
3182 [(set (match_operand:SI 0 "register_operand" "")
3184 (match_operator:CC 4 "predicate_operator"
3185 [(match_operand:CC 1 "register_operand" "c,c")
3187 (neg:SI (match_operand:SI 2 "gr_reg_or_22bit_operand" ""))
3188 (match_operand:SI 3 "gr_reg_or_22bit_operand" "")))]
3189 "reload_completed && rtx_equal_p (operands[0], operands[3])"
3193 (neg:SI (match_dup 2))))]
3197 [(set (match_operand:SI 0 "register_operand" "")
3199 (match_operator:CC 4 "predicate_operator"
3200 [(match_operand:CC 1 "register_operand" "c,c")
3202 (neg:SI (match_operand:SI 2 "gr_reg_or_22bit_operand" ""))
3203 (match_operand:SI 3 "gr_reg_or_22bit_operand" "")))]
3207 (set (match_dup 0) (neg:SI (match_dup 2))))
3210 (set (match_dup 0) (match_dup 3)))]
3213 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
3214 CCmode, operands[1], const0_rtx);
3218 ;; ::::::::::::::::::::
3220 ;; :: Call and branch instructions
3222 ;; ::::::::::::::::::::
3224 ;; Subroutine call instruction returning no value. Operand 0 is the function
3225 ;; to call; operand 1 is the number of bytes of arguments pushed (in mode
3226 ;; `SImode', except it is normally a
`const_int'); operand 2 is the number of
3227 ;; registers used as operands.
3229 ;; On most machines, operand 2 is not actually stored into the RTL pattern. It
3230 ;; is supplied for the sake of some RISC machines which need to put this
3231 ;; information into the assembler code; they can put it in the RTL instead of
3234 (define_expand "call"
3235 [(use (match_operand:DI 0 "" ""))
3236 (use (match_operand 1 "" ""))
3237 (use (match_operand 2 "" ""))
3238 (use (match_operand 3 "" ""))]
3242 /* ??? Stripping off the MEM isn't correct. Will lose alias info. */
3243 rtx addr = XEXP (operands[0], 0);
3244 enum machine_mode mode = GET_MODE (addr);
3246 if (TARGET_NO_PIC || TARGET_AUTO_PIC)
3247 emit_call_insn (gen_call_internal (addr, operands[1],
3248 gen_rtx_REG (DImode, R_BR (0))));
3250 /* If this is an indirect call, then we have the address of a descriptor. */
3251 else if (! symbolic_operand (addr, mode))
3252 emit_insn (gen_indirect_call_pic (addr, operands[1]));
3253 else if (TARGET_CONST_GP)
3254 emit_call_insn (gen_call_internal (addr, operands[1],
3255 gen_rtx_REG (DImode, R_BR (0))));
3257 emit_insn (gen_call_pic (addr, operands[1]));
3262 (define_expand "indirect_call_pic"
3263 [(set (match_dup 2) (reg:DI 1))
3264 (set (match_dup 3) (mem:DI (match_operand 0 "" "")))
3265 (set (match_dup 4) (plus:DI (match_dup 0) (const_int 8)))
3266 (set (reg:DI 1) (mem:DI (match_dup 4)))
3267 (parallel [(call (mem:DI (match_dup 3)) (match_operand 1 "" ""))
3269 (clobber (reg:DI 320))])
3270 (set (reg:DI 1) (match_dup 2))]
3274 operands[2] = ia64_gp_save_reg (0);
3275 operands[3] = gen_reg_rtx (DImode);
3276 operands[4] = gen_reg_rtx (DImode);
3279 ;; ??? Saving/restoring the GP register is not needed if we are calling
3280 ;; a function in the same module.
3282 (define_expand "call_pic"
3283 [(set (match_dup 2) (reg:DI 1))
3284 (parallel [(call (mem:DI (match_operand 0 "" "")) (match_operand 1 "" ""))
3286 (clobber (reg:DI 320))])
3287 (set (reg:DI 1) (match_dup 2))]
3291 /* ??? Using setjmp_operand is an unsatisfying solution. Should rethink. */
3292 operands[2] = ia64_gp_save_reg (setjmp_operand (XEXP (operands[0], 0),
3296 (define_insn "call_internal"
3297 [(call (mem:DI (match_operand:DI 0 "call_operand" "bi"))
3298 (match_operand 1 "" ""))
3299 (clobber (match_operand:DI 2 "register_operand" "=b"))]
3301 "br.call%+.many %2 = %0"
3302 [(set_attr "type" "B")])
3304 (define_insn "*call_internal1"
3305 [(call (mem:DI (match_operand:DI 0 "call_operand" "bi"))
3306 (match_operand 1 "" ""))
3308 (clobber (match_operand:DI 2 "register_operand" "=b"))]
3310 "br.call%+.many %2 = %0"
3311 [(set_attr "type" "B")])
3313 ;; Subroutine call instruction returning a value. Operand 0 is the hard
3314 ;; register in which the value is returned. There are three more operands, the
3315 ;; same as the three operands of the `call' instruction (but with numbers
3316 ;; increased by one).
3318 ;; Subroutines that return
`BLKmode' objects use the `call' insn.
3320 (define_expand "call_value"
3321 [(use (match_operand
0 "" ""))
3322 (use (match_operand:DI
1 "" ""))
3323 (use (match_operand
2 "" ""))
3324 (use (match_operand
3 "" ""))
3325 (use (match_operand
4 "" ""))]
3329 /* ??? Stripping off the MEM isn't correct. Will lose alias info. */
3330 rtx addr = XEXP (operands[
1],
0);
3331 enum machine_mode mode = GET_MODE (addr);
3333 if (TARGET_NO_PIC || TARGET_AUTO_PIC)
3334 emit_call_insn (gen_call_value_internal (operands[
0], addr, operands[
2],
3335 gen_rtx_REG (DImode, R_BR (
0))));
3337 /* If this is an indirect call, then we have the address of a descriptor. */
3338 else if (! symbolic_operand (addr, mode))
3340 /* This is for HFA returns. */
3341 if (GET_CODE (operands[
0]) == PARALLEL)
3342 emit_insn (gen_indirect_call_multiple_values_pic (operands[
0], addr,
3345 emit_insn (gen_indirect_call_value_pic (operands[
0], addr,
3348 else if (TARGET_CONST_GP)
3349 emit_call_insn (gen_call_value_internal (operands[
0], addr, operands[
2],
3350 gen_rtx_REG (DImode, R_BR (
0))));
3351 /* This is for HFA returns. */
3352 else if (GET_CODE (operands[
0]) == PARALLEL)
3353 emit_insn (gen_call_multiple_values_pic (operands[
0], addr, operands[
2]));
3355 emit_insn (gen_call_value_pic (operands[
0], addr, operands[
2]));
3360 (define_expand "indirect_call_value_pic"
3361 [(set (match_dup
3) (reg:DI
1))
3362 (set (match_dup
4) (mem:DI (match_operand
1 "" "")))
3363 (set (match_dup
5) (plus:DI (match_dup
1) (const_int
8)))
3364 (set (reg:DI
1) (mem:DI (match_dup
5)))
3365 (parallel [(set (match_operand
0 "" "")
3366 (call (mem:DI (match_dup
4)) (match_operand
2 "" "")))
3368 (clobber (reg:DI
320))])
3369 (set (reg:DI
1) (match_dup
3))]
3373 operands[
3] = ia64_gp_save_reg (
0);
3374 operands[
4] = gen_reg_rtx (DImode);
3375 operands[
5] = gen_reg_rtx (DImode);
3378 (define_expand "indirect_call_multiple_values_pic"
3379 [(set (match_dup
3) (reg:DI
1))
3380 (set (match_dup
4) (mem:DI (match_operand
1 "" "")))
3381 (set (match_dup
5) (plus:DI (match_dup
1) (const_int
8)))
3382 (set (reg:DI
1) (mem:DI (match_dup
5)))
3383 (match_par_dup
6 [(set (match_operand
0 "" "")
3384 (call (mem:DI (match_dup
4))
3385 (match_operand
2 "" "")))
3387 (clobber (reg:DI
320))])
3388 (set (reg:DI
1) (match_dup
3))]
3396 operands[
3] = ia64_gp_save_reg (
0);
3397 operands[
4] = gen_reg_rtx (DImode);
3398 operands[
5] = gen_reg_rtx (DImode);
3400 /* This code is the same as the code in call_multiple_values_pic, except
3401 that op3 was replaced with op6 and op1 was replaced with op4. */
3402 call = gen_rtx_CALL (VOIDmode, gen_rtx_MEM (DImode, operands[
4]),
3405 count = XVECLEN (operands[
0],
0);
3406 operands[
6] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count +
2));
3408 XVECEXP (operands[
6],
0,
0)
3409 = gen_rtx_SET (VOIDmode, XEXP (XVECEXP (operands[
0],
0,
0),
0), call);
3411 XVECEXP (operands[
6],
0,
1)
3412 = gen_rtx_USE (DImode, gen_rtx_REG (DImode, GR_REG (
1)));
3413 XVECEXP (operands[
6],
0,
2)
3414 = gen_rtx_CLOBBER (DImode, gen_rtx_REG (DImode, BR_REG (
0)));
3416 for (i =
1; i < count; i++)
3417 XVECEXP (operands[
6],
0, i +
2)
3418 = gen_rtx_SET (VOIDmode, XEXP (XVECEXP (operands[
0],
0, i),
0), call);
3422 ;; ??? Saving/restoring the GP register is not needed if we are calling
3423 ;; a function in the same module.
3425 (define_expand "call_value_pic"
3426 [(set (match_dup
3) (reg:DI
1))
3427 (parallel [(set (match_operand
0 "" "")
3428 (call (mem:DI (match_operand
1 "" ""))
3429 (match_operand
2 "" "")))
3431 (clobber (reg:DI
320))])
3432 (set (reg:DI
1) (match_dup
3))]
3436 /* ??? Using setjmp_operand is an unsatisfying solution. Should rethink. */
3437 operands[
3] = ia64_gp_save_reg (setjmp_operand (XEXP (operands[
1],
0),
3441 ;; ??? Saving/restoring the GP register is not needed if we are calling
3442 ;; a function in the same module.
3444 (define_expand "call_multiple_values_pic"
3445 [(set (match_dup
4) (reg:DI
1))
3446 (match_par_dup
3 [(set (match_operand
0 "" "")
3447 (call (mem:DI (match_operand
1 "" ""))
3448 (match_operand
2 "" "")))
3450 (clobber (reg:DI
320))])
3451 (set (reg:DI
1) (match_dup
4))]
3459 operands[
4] = ia64_gp_save_reg (
0);
3461 call = gen_rtx_CALL (VOIDmode, gen_rtx_MEM (DImode, operands[
1]),
3464 count = XVECLEN (operands[
0],
0);
3465 operands[
3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count +
2));
3467 XVECEXP (operands[
3],
0,
0)
3468 = gen_rtx_SET (VOIDmode, XEXP (XVECEXP (operands[
0],
0,
0),
0), call);
3470 XVECEXP (operands[
3],
0,
1)
3471 = gen_rtx_USE (DImode, gen_rtx_REG (DImode, GR_REG (
1)));
3472 XVECEXP (operands[
3],
0,
2)
3473 = gen_rtx_CLOBBER (DImode, gen_rtx_REG (DImode, BR_REG (
0)));
3475 for (i =
1; i < count; i++)
3476 XVECEXP (operands[
3],
0, i +
2)
3477 = gen_rtx_SET (VOIDmode, XEXP (XVECEXP (operands[
0],
0, i),
0), call);
3480 (define_insn "call_value_internal"
3481 [(set (match_operand
0 "register_operand" "=rf")
3482 (call (mem:DI (match_operand:DI
1 "call_operand" "bi"))
3483 (match_operand
2 "" "")))
3484 (clobber (match_operand:DI
3 "register_operand" "=b"))]
3486 "br.call%+.many %
3 = %
1"
3487 [(set_attr "type" "B")])
3489 (define_insn "*call_value_internal1"
3490 [(set (match_operand
0 "register_operand" "=rf")
3491 (call (mem:DI (match_operand:DI
1 "call_operand" "bi"))
3492 (match_operand
2 "" "")))
3494 (clobber (match_operand:DI
3 "register_operand" "=b"))]
3496 "br.call%+.many %
3 = %
1"
3497 [(set_attr "type" "B")])
3499 (define_insn "*call_multiple_values_internal1"
3500 [(match_parallel
0 "call_multiple_values_operation"
3501 [(set (match_operand
1 "register_operand" "=rf")
3502 (call (mem:DI (match_operand:DI
2 "call_operand" "bi"))
3503 (match_operand
3 "" "")))
3505 (clobber (match_operand:DI
4 "register_operand" "=b"))])]
3507 "br.call%+.many %
4 = %
2"
3508 [(set_attr "type" "B")])
3510 ;; Call subroutine returning any type.
3512 (define_expand "untyped_call"
3513 [(parallel [(call (match_operand
0 "" "")
3515 (match_operand
1 "" "")
3516 (match_operand
2 "" "")])]
3522 emit_call_insn (gen_call (operands[
0], const0_rtx, NULL, const0_rtx));
3524 for (i =
0; i < XVECLEN (operands[
2],
0); i++)
3526 rtx set = XVECEXP (operands[
2],
0, i);
3527 emit_move_insn (SET_DEST (set), SET_SRC (set));
3530 /* The optimizer does not know that the call sets the function value
3531 registers we stored in the result block. We avoid problems by
3532 claiming that all hard registers are used and clobbered at this
3534 emit_insn (gen_blockage ());
3539 (define_insn "return_internal"
3541 (use (match_operand:DI
0 "register_operand" "b"))]
3543 "br.ret.sptk.many %
0"
3544 [(set_attr "type" "B")])
3546 (define_insn "return"
3548 "ia64_direct_return ()"
3549 "br.ret.sptk.many rp"
3550 [(set_attr "type" "B")])
3552 (define_insn "*return_true"
3554 (if_then_else (match_operator
0 "predicate_operator"
3555 [(match_operand:CC
1 "register_operand" "c")
3559 "ia64_direct_return ()"
3560 "(%J0) br.ret%+.many rp"
3561 [(set_attr "type" "B")
3562 (set_attr "predicable" "no")])
3564 (define_insn "*return_false"
3566 (if_then_else (match_operator
0 "predicate_operator"
3567 [(match_operand:CC
1 "register_operand" "c")
3571 "ia64_direct_return ()"
3572 "(%j0) br.ret%+.many rp"
3573 [(set_attr "type" "B")
3574 (set_attr "predicable" "no")])
3577 [(set (pc) (label_ref (match_operand
0 "" "")))]
3580 [(set_attr "type" "B")])
3582 (define_insn "indirect_jump"
3583 [(set (pc) (match_operand:DI
0 "register_operand" "b"))]
3586 [(set_attr "type" "B")])
3588 (define_expand "tablejump"
3589 [(match_operand:DI
0 "register_operand" "")
3590 (match_operand
1 "" "")]
3594 rtx tmp1 = gen_reg_rtx (DImode);
3595 rtx tmp2 = gen_reg_rtx (DImode);
3597 emit_move_insn (tmp1, gen_rtx_LABEL_REF (Pmode, operands[
1]));
3598 emit_insn (gen_adddi3 (tmp2, operands[
0], tmp1));
3599 emit_jump_insn (gen_tablejump_internal (tmp2, operands[
1]));
3603 (define_insn "tablejump_internal"
3604 [(set (pc) (match_operand:DI
0 "register_operand" "b"))
3605 (use (label_ref (match_operand
1 "" "")))]
3608 [(set_attr "type" "B")])
3611 ;; ::::::::::::::::::::
3613 ;; :: Prologue and Epilogue instructions
3615 ;; ::::::::::::::::::::
3617 (define_expand "prologue"
3622 ia64_expand_prologue ();
3626 (define_expand "epilogue"
3631 ia64_expand_epilogue ();
3635 ;; This prevents the scheduler from moving the SP decrement past FP-relative
3636 ;; stack accesses. This is the same as adddi3 plus the extra set.
3638 (define_insn "prologue_allocate_stack"
3639 [(set (match_operand:DI
0 "register_operand" "=r,r,r")
3640 (plus:DI (match_operand:DI
1 "register_operand" "%r,r,a")
3641 (match_operand:DI
2 "gr_reg_or_22bit_operand" "r,I,J")))
3642 (set (match_operand:DI
3 "register_operand" "=r,r,r")
3649 [(set_attr "type" "A")])
3651 ;; This prevents the scheduler from moving the SP restore past FP-relative
3652 ;; stack accesses. This is similar to movdi plus the extra set.
3654 (define_insn "epilogue_deallocate_stack"
3655 [(set (match_operand:DI
0 "register_operand" "=r")
3656 (match_operand:DI
1 "register_operand" "+r"))
3657 (set (match_dup
1) (match_dup
1))]
3660 [(set_attr "type" "A")])
3662 ;; Allocate a new register frame.
3664 (define_insn "alloc"
3665 [(set (match_operand:DI
0 "register_operand" "=r")
3666 (unspec_volatile:DI [(const_int
0)]
0))
3667 (use (match_operand:DI
1 "const_int_operand" "i"))
3668 (use (match_operand:DI
2 "const_int_operand" "i"))
3669 (use (match_operand:DI
3 "const_int_operand" "i"))
3670 (use (match_operand:DI
4 "const_int_operand" "i"))]
3672 "alloc %
0 = ar.pfs, %
1, %
2, %
3, %
4"
3673 [(set_attr "type" "M")
3674 (set_attr "predicable" "no")])
3677 (define_expand "gr_spill"
3678 [(parallel [(set (match_operand:DI
0 "memory_operand" "=m")
3679 (unspec:DI [(match_operand:DI
1 "register_operand" "r")
3680 (match_operand:DI
2 "const_int_operand" "")]
1))
3681 (clobber (match_dup
3))])]
3683 "operands[
3] = gen_rtx_REG (DImode, AR_UNAT_REGNUM);")
3685 (define_insn "gr_spill_internal"
3686 [(set (match_operand:DI
0 "memory_operand" "=m")
3687 (unspec:DI [(match_operand:DI
1 "register_operand" "r")
3688 (match_operand:DI
2 "const_int_operand" "")]
1))
3689 (clobber (match_operand:DI
3 "register_operand" ""))]
3691 ".mem.offset %
2,
0\;st8.spill %
0 = %
1%P0"
3692 [(set_attr "type" "M")])
3695 (define_expand "gr_restore"
3696 [(parallel [(set (match_operand:DI
0 "register_operand" "=r")
3697 (unspec:DI [(match_operand:DI
1 "memory_operand" "m")
3698 (match_operand:DI
2 "const_int_operand" "")]
2))
3699 (use (match_dup
3))])]
3701 "operands[
3] = gen_rtx_REG (DImode, AR_UNAT_REGNUM);")
3703 (define_insn "gr_restore_internal"
3704 [(set (match_operand:DI
0 "register_operand" "=r")
3705 (unspec:DI [(match_operand:DI
1 "memory_operand" "m")
3706 (match_operand:DI
2 "const_int_operand" "")]
2))
3707 (use (match_operand:DI
3 "register_operand" ""))]
3709 ".mem.offset %
2,
0\;ld8.fill %
0 = %
1%P1"
3710 [(set_attr "type" "M")])
3712 (define_insn "fr_spill"
3713 [(set (match_operand:TF
0 "memory_operand" "=m")
3714 (unspec:TF [(match_operand:TF
1 "register_operand" "f")]
3))]
3716 "stf.spill %
0 = %
1%P0"
3717 [(set_attr "type" "M")])
3719 (define_insn "fr_restore"
3720 [(set (match_operand:TF
0 "register_operand" "=f")
3721 (unspec:TF [(match_operand:TF
1 "memory_operand" "m")]
4))]
3723 "ldf.fill %
0 = %
1%P1"
3724 [(set_attr "type" "M")])
3726 (define_insn "bsp_value"
3727 [(set (match_operand:DI
0 "register_operand" "=r")
3728 (unspec:DI [(const_int
0)]
20))]
3731 [(set_attr "type" "I")])
3733 (define_insn "set_bsp"
3734 [(unspec_volatile [(const_int
0)]
5)
3735 (use (match_operand:DI
0 "register_operand" "r"))]
3737 "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"
3738 [(set_attr "type" "unknown")
3739 (set_attr "predicable" "no")])
3741 (define_insn "flushrs"
3742 [(unspec [(const_int
0)]
21)]
3745 [(set_attr "type" "M")])
3747 ;; ::::::::::::::::::::
3749 ;; :: Miscellaneous instructions
3751 ;; ::::::::::::::::::::
3753 ;; ??? Emiting a NOP instruction isn't very useful. This should probably
3754 ;; be emitting ";;" to force a break in the instruction packing.
3756 ;; No operation, needed in case the user uses -g but not -O.
3761 [(set_attr "type" "unknown")])
3763 ;; Pseudo instruction that prevents the scheduler from moving code above this
3765 (define_insn "blockage"
3766 [(unspec_volatile [(const_int
0)]
1)]
3769 [(set_attr "type" "unknown")
3770 (set_attr "predicable" "no")])
3772 (define_insn "insn_group_barrier"
3773 [(unspec_volatile [(const_int
0)]
2)]
3776 [(set_attr "type" "S")
3777 (set_attr "predicable" "no")])
3780 ;; Non-local goto support.
3782 (define_expand "save_stack_nonlocal"
3783 [(use (match_operand:OI
0 "memory_operand" ""))
3784 (use (match_operand:DI
1 "register_operand" ""))]
3788 emit_library_call (gen_rtx_SYMBOL_REF (Pmode,
3789 \"__ia64_save_stack_nonlocal
\"),
3790 0, VOIDmode,
2, XEXP (operands[
0],
0), Pmode,
3791 operands[
1], Pmode);
3795 (define_expand "nonlocal_goto"
3796 [(use (match_operand
0 "general_operand" ""))
3797 (use (match_operand
1 "general_operand" ""))
3798 (use (match_operand
2 "general_operand" ""))
3799 (use (match_operand
3 "general_operand" ""))]
3803 emit_library_call (gen_rtx_SYMBOL_REF (Pmode,
\"__ia64_nonlocal_goto
\"),
3806 copy_to_reg (XEXP (operands[
2],
0)), Pmode,
3807 operands[
3], Pmode);
3812 ;; Restore the GP after the exception/longjmp. The preceeding call will
3813 ;; have tucked it away.
3814 (define_expand "exception_receiver"
3815 [(set (reg:DI
1) (match_dup
0))]
3817 "operands[
0] = ia64_gp_save_reg (
0);")
3819 ;; The rest of the setjmp processing happens with the nonlocal_goto expander.
3820 ;; ??? This is not tested.
3821 (define_expand "builtin_setjmp_setup"
3822 [(use (match_operand:DI
0 "" ""))]
3826 emit_move_insn (ia64_gp_save_reg (
0), gen_rtx_REG (DImode, GR_REG (
1)));
3830 (define_expand "builtin_setjmp_receiver"
3831 [(use (match_operand:DI
0 "" ""))]
3835 emit_move_insn (gen_rtx_REG (DImode, GR_REG (
1)), ia64_gp_save_reg (
0));
3839 (define_expand "eh_epilogue"
3840 [(use (match_operand:DI
0 "register_operand" "r"))
3841 (use (match_operand:DI
1 "register_operand" "r"))
3842 (use (match_operand:DI
2 "register_operand" "r"))]
3846 rtx bsp = gen_rtx_REG (Pmode,
10);
3847 rtx sp = gen_rtx_REG (Pmode,
9);
3849 if (GET_CODE (operands[
0]) != REG || REGNO (operands[
0]) !=
10)
3851 emit_move_insn (bsp, operands[
0]);
3854 if (GET_CODE (operands[
2]) != REG || REGNO (operands[
2]) !=
9)
3856 emit_move_insn (sp, operands[
2]);
3859 emit_insn (gen_rtx_USE (VOIDmode, sp));
3860 emit_insn (gen_rtx_USE (VOIDmode, bsp));
3862 cfun->machine->ia64_eh_epilogue_sp = sp;
3863 cfun->machine->ia64_eh_epilogue_bsp = bsp;
3866 ;; Builtin apply support.
3868 (define_expand "restore_stack_nonlocal"
3869 [(use (match_operand:DI
0 "register_operand" ""))
3870 (use (match_operand:OI
1 "memory_operand" ""))]
3874 emit_library_call (gen_rtx_SYMBOL_REF (Pmode,
3875 \"__ia64_restore_stack_nonlocal
\"),
3877 copy_to_reg (XEXP (operands[
1],
0)), Pmode);
3882 ;;; Intrinsics support.
3885 [(set (mem:BLK (match_dup
0))
3886 (unspec:BLK [(mem:BLK (match_dup
0))]
12))]
3890 operands[
0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (DImode));
3891 MEM_VOLATILE_P (operands[
0]) =
1;
3894 (define_insn "*mf_internal"
3895 [(set (match_operand:BLK
0 "" "")
3896 (unspec:BLK [(match_operand:BLK
1 "" "")]
12))]
3899 [(set_attr "type" "M")])
3901 (define_insn "fetchadd_acq_si"
3902 [(set (match_operand:SI
0 "gr_register_operand" "=r")
3904 (set (match_operand:SI
1 "not_postinc_memory_operand" "+S")
3905 (unspec:SI [(match_dup
1)
3906 (match_operand:SI
2 "fetchadd_operand" "n")]
19))]
3908 "fetchadd4.acq %
0 = %
1, %
2"
3909 [(set_attr "type" "M")])
3911 (define_insn "fetchadd_acq_di"
3912 [(set (match_operand:DI
0 "gr_register_operand" "=r")
3914 (set (match_operand:DI
1 "not_postinc_memory_operand" "+S")
3915 (unspec:DI [(match_dup
1)
3916 (match_operand:DI
2 "fetchadd_operand" "n")]
19))]
3918 "fetchadd8.acq %
0 = %
1, %
2"
3919 [(set_attr "type" "M")])
3921 (define_insn "cmpxchg_acq_si"
3922 [(set (match_operand:SI
0 "gr_register_operand" "=r")
3924 (set (match_operand:SI
1 "not_postinc_memory_operand" "+S")
3925 (unspec:SI [(match_dup
1)
3926 (match_operand:SI
2 "gr_register_operand" "r")
3927 (match_operand:SI
3 "ar_ccv_reg_operand" "")]
13))]
3929 "cmpxchg4.acq %
0 = %
1, %
2, %
3"
3930 [(set_attr "type" "M")])
3932 (define_insn "cmpxchg_acq_di"
3933 [(set (match_operand:DI
0 "gr_register_operand" "=r")
3935 (set (match_operand:DI
1 "not_postinc_memory_operand" "+S")
3936 (unspec:DI [(match_dup
1)
3937 (match_operand:DI
2 "gr_register_operand" "r")
3938 (match_operand:DI
3 "ar_ccv_reg_operand" "")]
13))]
3940 "cmpxchg8.acq %
0 = %
1, %
2, %
3"
3941 [(set_attr "type" "M")])
3943 (define_insn "xchgsi"
3944 [(set (match_operand:SI
0 "gr_register_operand" "=r")
3945 (match_operand:SI
1 "not_postinc_memory_operand" "+S"))
3947 (match_operand:SI
2 "gr_register_operand" "r"))]
3950 [(set_attr "type" "M")])
3952 (define_insn "xchgdi"
3953 [(set (match_operand:DI
0 "gr_register_operand" "=r")
3954 (match_operand:DI
1 "not_postinc_memory_operand" "+S"))
3956 (match_operand:DI
2 "gr_register_operand" "r"))]
3959 [(set_attr "type" "M")])
3964 [(match_operator
0 "predicate_operator"
3965 [(match_operand:CC
1 "register_operand" "c")
3970 (define_insn "pred_rel_mutex"
3971 [(unspec_volatile [(match_operand:CC
0 "register_operand" "c")]
7)]
3973 ".pred.rel.mutex %
0, %I0"
3974 [(set_attr "type" "unknown")
3975 (set_attr "predicable" "no")])
3977 (define_insn "safe_across_calls_all"
3978 [(unspec_volatile [(const_int
0)]
8)]
3980 ".pred.safe_across_calls p1-p63"
3981 [(set_attr "type" "unknown")
3982 (set_attr "predicable" "no")])
3984 (define_insn "safe_across_calls_normal"
3985 [(unspec_volatile [(const_int
0)]
9)]
3989 emit_safe_across_calls (asm_out_file);
3992 [(set_attr "type" "unknown")
3993 (set_attr "predicable" "no")])