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.
71 ;; 2 insn_group_barrier
74 ;; 8 pred.safe_across_calls all
75 ;; 9 pred.safe_across_calls normal
77 ;; ::::::::::::::::::::
81 ;; ::::::::::::::::::::
83 ;; Instruction type. This primarily determines how instructions can be
84 ;; packed in bundles, and secondarily affects scheduling to function units.
86 ;; A alu, can go in I or M syllable of a bundle
91 ;; L long immediate, takes two syllables
94 ;; ??? Should not have any pattern with type unknown. Perhaps add code to
95 ;; check this in md_reorg? Currently use unknown for patterns which emit
96 ;; multiple instructions, patterns which emit 0 instructions, and patterns
97 ;; which emit instruction that can go in any slot (e.g. nop).
99 (define_attr "type" "unknown,A,I,M,F,B,L,S" (const_string "unknown"))
101 ;; Predication. True iff this instruction can be predicated.
103 (define_attr "predicable" "no,yes" (const_string "yes"))
106 ;; ::::::::::::::::::::
110 ;; ::::::::::::::::::::
112 ;; Each usage of a function units by a class of insns is specified with a
113 ;; `define_function_unit' expression, which looks like this:
114 ;; (define_function_unit NAME MULTIPLICITY SIMULTANEITY TEST READY-DELAY
115 ;; ISSUE-DELAY [CONFLICT-LIST])
117 ;; This default scheduling info seeks to pack instructions into bundles
118 ;; efficiently to reduce code size, so we just list how many of each
119 ;; instruction type can go in a bundle. ISSUE_RATE is set to 3.
121 ;; ??? Add scheduler ready-list hook (MD_SCHED_REORDER) that orders
122 ;; instructions, so that the next instruction can fill the next bundle slot.
123 ;; This really needs to know where the stop bits are though.
125 ;; ??? Use MD_SCHED_REORDER to put alloc first instead of using an unspec
126 ;; volatile. Use ADJUST_PRIORITY to set the priority of alloc very high to
127 ;; make it schedule first.
129 ;; ??? Modify the md_reorg code that emits stop bits so that instead of putting
130 ;; them in the last possible place, we put them in places where bundles allow
131 ;; them. This should reduce code size, but may decrease performance if we end
132 ;; up with more stop bits than the minimum we need.
134 ;; Alu instructions can execute on either the integer or memory function
135 ;; unit. We indicate this by defining an alu function unit, and then marking
136 ;; it as busy everytime we issue a integer or memory type instruction.
138 (define_function_unit "alu" 3 1 (eq_attr "type" "A,I,M") 1 0)
140 (define_function_unit "integer" 2 1 (eq_attr "type" "I") 1 0)
142 (define_function_unit "memory" 3 1 (eq_attr "type" "M") 1 0)
144 (define_function_unit "floating_point" 1 1 (eq_attr "type" "F") 1 0)
146 (define_function_unit "branch" 3 1 (eq_attr "type" "B") 1 0)
148 ;; ??? This isn't quite right, because we can only fit two insns in a bundle
149 ;; when using an L type instruction. That isn't modeled currently.
151 (define_function_unit "long_immediate" 1 1 (eq_attr "type" "L") 1 0)
154 ;; ::::::::::::::::::::
158 ;; ::::::::::::::::::::
160 (define_expand "movqi"
161 [(set (match_operand:QI 0 "general_operand" "")
162 (match_operand:QI 1 "general_operand" ""))]
166 if (! reload_in_progress && ! reload_completed
167 && ! ia64_move_ok (operands[0], operands[1]))
168 operands[1] = force_reg (QImode, operands[1]);
171 ;; Errata 72 implies that we cannot use predicated loads and stores
172 ;; on affected systems. Reuse TARGET_A_STEP for convenience.
174 ;; ??? It would be convenient at this point if the cond_exec pattern
175 ;; expander understood non-constant conditions on attributes. Failing
176 ;; that we have to replicate patterns.
178 (define_insn "*movqicc_astep"
180 (match_operator 2 "predicate_operator"
181 [(match_operand:CC 3 "register_operand" "c,c,c,c,c")
183 (set (match_operand:QI 0 "register_operand" "=r,r, r,*f,*f")
184 (match_operand:QI 1 "nonmemory_operand" "rO,J,*f,rO,*f")))]
185 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
188 (%J2) addl %0 = %1, r0
189 (%J2) getf.sig %0 = %1
190 (%J2) setf.sig %0 = %r1
192 [(set_attr "type" "A,A,M,M,F")
193 (set_attr "predicable" "no")])
195 (define_insn "*movqi_internal_astep"
196 [(set (match_operand:QI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
197 (match_operand:QI 1 "move_operand" "rO,J,m,rO,*f,rO,*f"))]
198 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
207 [(set_attr "type" "A,A,M,M,M,M,F")
208 (set_attr "predicable" "no")])
210 (define_insn "*movqi_internal"
211 [(set (match_operand:QI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
212 (match_operand:QI 1 "move_operand" "rO,J,m,rO,*f,rO,*f"))]
213 "! TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
222 [(set_attr "type" "A,A,M,M,M,M,F")])
224 (define_expand "movhi"
225 [(set (match_operand:HI 0 "general_operand" "")
226 (match_operand:HI 1 "general_operand" ""))]
230 if (! reload_in_progress && ! reload_completed
231 && ! ia64_move_ok (operands[0], operands[1]))
232 operands[1] = force_reg (HImode, operands[1]);
235 ;; Errata 72 workaround.
236 (define_insn "*movhicc_astep"
238 (match_operator 2 "predicate_operator"
239 [(match_operand:CC 3 "register_operand" "c,c,c,c,c")
241 (set (match_operand:HI 0 "register_operand" "=r,r, r,*f,*f")
242 (match_operand:HI 1 "nonmemory_operand" "rO,J,*f,rO,*f")))]
243 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
246 (%J2) addl %0 = %1, r0
247 (%J2) getf.sig %0 = %1
248 (%J2) setf.sig %0 = %r1
250 [(set_attr "type" "A,A,M,M,F")
251 (set_attr "predicable" "no")])
253 (define_insn "*movhi_internal_astep"
254 [(set (match_operand:HI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
255 (match_operand:HI 1 "move_operand" "rO,J,m,rO,*f,rO,*f"))]
256 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
265 [(set_attr "type" "A,A,M,M,M,M,F")
266 (set_attr "predicable" "no")])
268 (define_insn "*movhi_internal"
269 [(set (match_operand:HI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
270 (match_operand:HI 1 "move_operand" "rO,J,m,rO,*f,rO,*f"))]
271 "! TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
280 [(set_attr "type" "A,A,M,M,M,M,F")])
282 (define_expand "movsi"
283 [(set (match_operand:SI 0 "general_operand" "")
284 (match_operand:SI 1 "general_operand" ""))]
288 if (! reload_in_progress && ! reload_completed
289 && ! ia64_move_ok (operands[0], operands[1]))
290 operands[1] = force_reg (SImode, operands[1]);
293 ;; Errata 72 workaround.
294 (define_insn "*movsicc_astep"
296 (match_operator 2 "predicate_operator"
297 [(match_operand:CC 3 "register_operand" "c,c,c,c,c,c,c,c")
299 (set (match_operand:SI 0 "register_operand" "=r,r,r, r,*f,*f, r,*d")
300 (match_operand:SI 1 "nonmemory_operand" "rO,J,i,*f,rO,*f,*d,rK")))]
301 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
304 (%J2) addl %0 = %1, r0
306 (%J2) getf.sig %0 = %1
307 (%J2) setf.sig %0 = %r1
311 [(set_attr "type" "A,A,L,M,M,F,M,M")
312 (set_attr "predicable" "no")])
314 (define_insn "*movsi_internal_astep"
315 [(set (match_operand:SI 0 "destination_operand" "=r,r,r,r, m, r,*f,*f, r,*d")
316 (match_operand:SI 1 "move_operand" "rO,J,i,m,rO,*f,rO,*f,*d,rK"))]
317 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
329 [(set_attr "type" "A,A,L,M,M,M,M,F,M,M")
330 (set_attr "predicable" "no")])
332 (define_insn "*movsi_internal"
333 [(set (match_operand:SI 0 "destination_operand" "=r,r,r,r, m, r,*f,*f, r,*d")
334 (match_operand:SI 1 "move_operand" "rO,J,i,m,rO,*f,rO,*f,*d,rK"))]
335 "! TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
347 [(set_attr "type" "A,A,L,M,M,M,M,F,M,M")])
349 (define_expand "movdi"
350 [(set (match_operand:DI 0 "general_operand" "")
351 (match_operand:DI 1 "general_operand" ""))]
355 if (! reload_in_progress && ! reload_completed
356 && ! ia64_move_ok (operands[0], operands[1]))
357 operands[1] = force_reg (DImode, operands[1]);
358 if (! TARGET_NO_PIC && symbolic_operand (operands[1], DImode))
360 /* Before optimization starts, delay committing to any particular
361 type of PIC address load. If this function gets deferred, we
362 may acquire information that changes the value of the
363 sdata_symbolic_operand predicate. */
364 /* But don't delay for function pointers. Loading a function address
365 actually loads the address of the descriptor not the function.
366 If we represent these as SYMBOL_REFs, then they get cse'd with
367 calls, and we end up with calls to the descriptor address instead of
368 calls to the function address. Functions are not candidates for
370 if (rtx_equal_function_value_matters
371 && ! (GET_CODE (operands[1]) == SYMBOL_REF
372 && SYMBOL_REF_FLAG (operands[1])))
373 emit_insn (gen_movdi_symbolic (operands[0], operands[1]));
375 ia64_expand_load_address (operands[0], operands[1]);
380 ;; Errata 72 workaround.
383 (match_operator 2 "predicate_operator"
384 [(match_operand:CC 3 "register_operand" "c,c,c,c,c,c,c,c,c,c,c")
386 (set (match_operand:DI 0 "register_operand"
387 "=r,r,r, r,*f,*f, r,*b,*e, r,*d")
388 (match_operand:DI 1 "nonmemory_operand"
389 "rO,J,i,*f,rO,*f,*b*e,rO,rK,*d,rK")))]
390 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
393 static const char * const alt[] = {
394 \"(%J2) mov %0 = %r1\",
395 \"(%J2) addl %0 = %1, r0\",
396 \"(%J2) movl %0 = %1\",
397 \"(%J2) getf.sig %0 = %1\",
398 \"(%J2) setf.sig %0 = %r1\",
399 \"(%J2) mov %0 = %1\",
400 \"(%J2) mov %0 = %1\",
401 \"(%J2) mov %0 = %r1\",
402 \"(%J2) mov %0 = %1\",
403 \"(%J2) mov %0 = %1\",
404 \"(%J2) mov %0 = %1\"
407 /* We use 'i' for alternative 2 despite possible PIC problems.
409 If we define LEGITIMATE_CONSTANT_P such that symbols are not
410 allowed, then the compiler dumps the data into constant memory
411 instead of letting us read the values from the GOT. Similarly
412 if we use 'n' instead of 'i'.
414 Instead, we allow such insns through reload and then split them
415 afterward (even without optimization). Therefore, we should
416 never get so far with a symbolic operand. */
418 if (which_alternative == 2 && ! TARGET_NO_PIC
419 && symbolic_operand (operands[1], VOIDmode))
422 return alt[which_alternative];
424 [(set_attr "type" "A,A,L,M,M,F,I,I,I,M,M")
425 (set_attr "predicable" "no")])
427 ;; This is used during early compilation to delay the decision on
428 ;; how to refer to a variable as long as possible. This is especially
429 ;; important between initial rtl generation and optimization for
430 ;; deferred functions, since we may acquire additional information
431 ;; on the variables used in the meantime.
433 (define_insn_and_split "movdi_symbolic"
434 [(set (match_operand:DI 0 "register_operand" "=r")
435 (match_operand:DI 1 "symbolic_operand" "s"))
441 "ia64_expand_load_address (operands[0], operands[1]); DONE;")
443 (define_insn "*movdi_internal_astep"
444 [(set (match_operand:DI 0 "destination_operand"
445 "=r,r,r,r, m, r,*f,*f,*f, Q, r,*b,*e, r,*d, r,*c")
446 (match_operand:DI 1 "move_operand"
447 "rO,J,i,m,rO,*f,rO,*f, Q,*f,*b*e,rO,rK,*d,rK,*c,rO"))]
448 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
451 static const char * const alt[] = {
453 \"addl %0 = %1, r0\",
455 \"ld8%O1 %0 = %1%P1\",
456 \"st8%Q0 %0 = %r1%P0\",
457 \"getf.sig %0 = %1\",
458 \"setf.sig %0 = %r1\",
471 if (which_alternative == 2 && ! TARGET_NO_PIC
472 && symbolic_operand (operands[1], VOIDmode))
475 return alt[which_alternative];
477 [(set_attr "type" "A,A,L,M,M,M,M,F,M,M,I,I,I,M,M,I,I")
478 (set_attr "predicable" "no")])
480 (define_insn "*movdi_internal"
481 [(set (match_operand:DI 0 "destination_operand"
482 "=r,r,r,r, m, r,*f,*f,*f, Q, r,*b,*e, r,*d, r,*c")
483 (match_operand:DI 1 "move_operand"
484 "rO,J,i,m,rO,*f,rO,*f, Q,*f,*b*e,rO,rK,*d,rK,*c,rO"))]
485 "! TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
488 static const char * const alt[] = {
490 \"%,addl %0 = %1, r0\",
492 \"%,ld8%O1 %0 = %1%P1\",
493 \"%,st8%Q0 %0 = %r1%P0\",
494 \"%,getf.sig %0 = %1\",
495 \"%,setf.sig %0 = %r1\",
497 \"%,ldf8 %0 = %1%P1\",
498 \"%,stf8 %0 = %1%P0\",
508 if (which_alternative == 2 && ! TARGET_NO_PIC
509 && symbolic_operand (operands[1], VOIDmode))
512 return alt[which_alternative];
514 [(set_attr "type" "A,A,L,M,M,M,M,F,M,M,I,I,I,M,M,I,I")])
517 [(set (match_operand:DI 0 "register_operand" "")
518 (match_operand:DI 1 "symbolic_operand" ""))]
519 "reload_completed && ! TARGET_NO_PIC"
523 ia64_expand_load_address (operands[0], operands[1]);
527 (define_expand "load_fptr"
529 (plus:DI (reg:DI 1) (match_operand:DI 1 "function_operand" "")))
530 (set (match_operand:DI 0 "register_operand" "") (match_dup 3))]
534 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
535 operands[3] = gen_rtx_MEM (DImode, operands[2]);
536 RTX_UNCHANGING_P (operands[3]) = 1;
539 (define_insn "*load_fptr_internal1"
540 [(set (match_operand:DI 0 "register_operand" "=r")
541 (plus:DI (reg:DI 1) (match_operand:DI 1 "function_operand" "s")))]
543 "addl %0 = @ltoff(@fptr(%1)), gp"
544 [(set_attr "type" "A")])
546 (define_insn "load_gprel"
547 [(set (match_operand:DI 0 "register_operand" "=r")
548 (plus:DI (reg:DI 1) (match_operand:DI 1 "sdata_symbolic_operand" "s")))]
550 "addl %0 = @gprel(%1), gp"
551 [(set_attr "type" "A")])
553 (define_insn "gprel64_offset"
554 [(set (match_operand:DI 0 "register_operand" "=r")
555 (minus:DI (match_operand:DI 1 "symbolic_operand" "") (reg:DI 1)))]
557 "movl %0 = @gprel(%1)"
558 [(set_attr "type" "L")])
560 (define_expand "load_gprel64"
562 (minus:DI (match_operand:DI 1 "symbolic_operand" "") (reg:DI 1)))
563 (set (match_operand:DI 0 "register_operand" "")
564 (plus:DI (reg:DI 1) (match_dup 2)))]
568 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
571 (define_expand "load_symptr"
573 (plus:DI (reg:DI 1) (match_operand:DI 1 "got_symbolic_operand" "")))
574 (set (match_operand:DI 0 "register_operand" "") (match_dup 3))]
578 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
579 operands[3] = gen_rtx_MEM (DImode, operands[2]);
580 RTX_UNCHANGING_P (operands[3]) = 1;
583 (define_insn "*load_symptr_internal1"
584 [(set (match_operand:DI 0 "register_operand" "=r")
585 (plus:DI (reg:DI 1) (match_operand:DI 1 "got_symbolic_operand" "s")))]
587 "addl %0 = @ltoff(%1), gp"
588 [(set_attr "type" "A")])
590 ;; With no offsettable memory references, we've got to have a scratch
591 ;; around to play with the second word.
592 (define_expand "movti"
593 [(parallel [(set (match_operand:TI 0 "general_operand" "")
594 (match_operand:TI 1 "general_operand" ""))
595 (clobber (match_scratch:DI 2 ""))])]
599 if (! reload_in_progress && ! reload_completed
600 && ! ia64_move_ok (operands[0], operands[1]))
601 operands[1] = force_reg (TImode, operands[1]);
604 (define_insn_and_split "*movti_internal"
605 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m")
606 (match_operand:TI 1 "general_operand" "ri,m,r"))
607 (clobber (match_scratch:DI 2 "=X,&r,&r"))]
608 "ia64_move_ok (operands[0], operands[1])"
614 rtx adj1, adj2, in[2], out[2];
617 adj1 = ia64_split_timode (in, operands[1], operands[2]);
618 adj2 = ia64_split_timode (out, operands[0], operands[2]);
621 if (reg_overlap_mentioned_p (out[0], in[1]))
623 if (reg_overlap_mentioned_p (out[1], in[0]))
634 emit_insn (gen_rtx_SET (VOIDmode, out[first], in[first]));
635 emit_insn (gen_rtx_SET (VOIDmode, out[!first], in[!first]));
638 [(set_attr "type" "unknown")
639 (set_attr "predicable" "no")])
641 ;; ??? SSA creates these. Can't allow memories since we don't have
642 ;; the scratch register. Fortunately combine will know how to add
643 ;; the clobber and scratch.
644 (define_insn_and_split "*movti_internal_reg"
645 [(set (match_operand:TI 0 "register_operand" "=r")
646 (match_operand:TI 1 "nonmemory_operand" "ri"))]
656 ia64_split_timode (in, operands[1], NULL_RTX);
657 ia64_split_timode (out, operands[0], NULL_RTX);
660 if (reg_overlap_mentioned_p (out[0], in[1]))
662 if (reg_overlap_mentioned_p (out[1], in[0]))
667 emit_insn (gen_rtx_SET (VOIDmode, out[first], in[first]));
668 emit_insn (gen_rtx_SET (VOIDmode, out[!first], in[!first]));
671 [(set_attr "type" "unknown")
672 (set_attr "predicable" "no")])
674 (define_expand "reload_inti"
675 [(parallel [(set (match_operand:TI 0 "register_operand" "=r")
676 (match_operand:TI 1 "" "m"))
677 (clobber (match_operand:TI 2 "register_operand" "=&r"))])]
681 unsigned int s_regno = REGNO (operands[2]);
682 if (s_regno == REGNO (operands[0]))
684 operands[2] = gen_rtx_REG (DImode, s_regno);
687 (define_expand "reload_outti"
688 [(parallel [(set (match_operand:TI 0 "" "=m")
689 (match_operand:TI 1 "register_operand" "r"))
690 (clobber (match_operand:TI 2 "register_operand" "=&r"))])]
694 unsigned int s_regno = REGNO (operands[2]);
695 if (s_regno == REGNO (operands[1]))
697 operands[2] = gen_rtx_REG (DImode, s_regno);
700 ;; Floating Point Moves
702 ;; Note - Patterns for SF mode moves are compulsory, but
703 ;; patterns for DF are optional, as GCC can synthesise them.
705 (define_expand "movsf"
706 [(set (match_operand:SF 0 "general_operand" "")
707 (match_operand:SF 1 "general_operand" ""))]
711 if (! reload_in_progress && ! reload_completed
712 && ! ia64_move_ok (operands[0], operands[1]))
713 operands[1] = force_reg (SFmode, operands[1]);
716 ;; Errata 72 workaround.
717 (define_insn "*movsfcc_astep"
719 (match_operator 2 "predicate_operator"
720 [(match_operand:CC 3 "register_operand" "c,c,c,c")
722 (set (match_operand:SF 0 "register_operand" "=f,*r, f,*r")
723 (match_operand:SF 1 "nonmemory_operand" "fG,fG,*r,*r")))]
724 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
727 (%J2) getf.s %0 = %F1
730 [(set_attr "type" "F,M,M,A")
731 (set_attr "predicable" "no")])
733 (define_insn "*movsf_internal_astep"
734 [(set (match_operand:SF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m")
735 (match_operand:SF 1 "general_operand" "fG,Q,fG,fG,*r,*r, m,*r"))]
736 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
746 [(set_attr "type" "F,M,M,M,M,A,M,M")
747 (set_attr "predicable" "no")])
749 (define_insn "*movsf_internal"
750 [(set (match_operand:SF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m")
751 (match_operand:SF 1 "general_operand" "fG,Q,fG,fG,*r,*r, m,*r"))]
752 "! TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
762 [(set_attr "type" "F,M,M,M,M,A,M,M")])
764 (define_expand "movdf"
765 [(set (match_operand:DF 0 "general_operand" "")
766 (match_operand:DF 1 "general_operand" ""))]
770 if (! reload_in_progress && ! reload_completed
771 && ! ia64_move_ok (operands[0], operands[1]))
772 operands[1] = force_reg (DFmode, operands[1]);
775 ;; Errata 72 workaround.
776 (define_insn "*movdfcc_astep"
778 (match_operator 2 "predicate_operator"
779 [(match_operand:CC 3 "register_operand" "c,c,c,c")
781 (set (match_operand:DF 0 "register_operand" "=f,*r, f,*r")
782 (match_operand:DF 1 "nonmemory_operand" "fG,fG,*r,*r")))]
783 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
786 (%J2) getf.d %0 = %F1
789 [(set_attr "type" "F,M,M,A")
790 (set_attr "predicable" "no")])
792 (define_insn "*movdf_internal_astep"
793 [(set (match_operand:DF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m")
794 (match_operand:DF 1 "general_operand" "fG,Q,fG,fG,*r,*r, m,*r"))]
795 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
805 [(set_attr "type" "F,M,M,M,M,A,M,M")
806 (set_attr "predicable" "no")])
808 (define_insn "*movdf_internal"
809 [(set (match_operand:DF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m")
810 (match_operand:DF 1 "general_operand" "fG,Q,fG,fG,*r,*r, m,*r"))]
811 "! TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
821 [(set_attr "type" "F,M,M,M,M,A,M,M")])
823 ;; With no offsettable memory references, we've got to have a scratch
824 ;; around to play with the second word if the variable winds up in GRs.
825 (define_expand "movtf"
826 [(set (match_operand:TF 0 "general_operand" "")
827 (match_operand:TF 1 "general_operand" ""))]
831 /* We must support TFmode loads into general registers for stdarg/vararg
832 and unprototyped calls. We split them into DImode loads for convenience.
833 We don't need TFmode stores from general regs, because a stdarg/vararg
834 routine does a block store to memory of unnamed arguments. */
835 if (GET_CODE (operands[0]) == REG
836 && GR_REGNO_P (REGNO (operands[0])))
838 /* We're hoping to transform everything that deals with TFmode
839 quantities and GR registers early in the compiler. */
843 /* Struct to register can just use TImode instead. */
844 if ((GET_CODE (operands[1]) == SUBREG
845 && GET_MODE (SUBREG_REG (operands[1])) == TImode)
846 || (GET_CODE (operands[1]) == REG
847 && GR_REGNO_P (REGNO (operands[1]))))
849 emit_move_insn (gen_rtx_REG (TImode, REGNO (operands[0])),
850 SUBREG_REG (operands[1]));
854 if (GET_CODE (operands[1]) == CONST_DOUBLE)
856 emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0])),
857 operand_subword (operands[1], 0, 0, DImode));
858 emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0]) + 1),
859 operand_subword (operands[1], 1, 0, DImode));
863 /* If the quantity is in a register not known to be GR, spill it. */
864 if (register_operand (operands[1], TFmode))
865 operands[1] = spill_tfmode_operand (operands[1], 1);
867 if (GET_CODE (operands[1]) == MEM)
871 out[WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[0]));
872 out[!WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[0])+1);
874 emit_move_insn (out[0], change_address (operands[1], DImode, NULL));
875 emit_move_insn (out[1],
876 change_address (operands[1], DImode,
877 plus_constant (XEXP (operands[1], 0),
885 if (! reload_in_progress && ! reload_completed)
887 operands[0] = spill_tfmode_operand (operands[0], 0);
888 operands[1] = spill_tfmode_operand (operands[1], 0);
890 if (! ia64_move_ok (operands[0], operands[1]))
891 operands[1] = force_reg (TFmode, operands[1]);
895 ;; ??? There's no easy way to mind volatile acquire/release semantics.
897 ;; Errata 72 workaround.
898 (define_insn "*movtfcc_astep"
900 (match_operator 2 "predicate_operator"
901 [(match_operand:CC 3 "register_operand" "c")
903 (set (match_operand:TF 0 "register_operand" "=f")
904 (match_operand:TF 1 "nonmemory_operand" "fG")))]
905 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
907 [(set_attr "type" "F")
908 (set_attr "predicable" "no")])
910 (define_insn "*movtf_internal_astep"
911 [(set (match_operand:TF 0 "destination_tfmode_operand" "=f,f, m")
912 (match_operand:TF 1 "general_tfmode_operand" "fG,m,fG"))]
913 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
918 [(set_attr "type" "F,M,M")
919 (set_attr "predicable" "no")])
921 (define_insn "*movtf_internal"
922 [(set (match_operand:TF 0 "destination_tfmode_operand" "=f,f, m")
923 (match_operand:TF 1 "general_tfmode_operand" "fG,m,fG"))]
924 "! TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
929 [(set_attr "type" "F,M,M")])
931 ;; ::::::::::::::::::::
935 ;; ::::::::::::::::::::
937 ;; Signed conversions from a smaller integer to a larger integer
939 (define_insn "extendqidi2"
940 [(set (match_operand:DI 0 "gr_register_operand" "=r")
941 (sign_extend:DI (match_operand:QI 1 "gr_register_operand" "r")))]
944 [(set_attr "type" "I")])
946 (define_insn "extendhidi2"
947 [(set (match_operand:DI 0 "gr_register_operand" "=r")
948 (sign_extend:DI (match_operand:HI 1 "gr_register_operand" "r")))]
951 [(set_attr "type" "I")])
953 (define_insn "extendsidi2"
954 [(set (match_operand:DI 0 "grfr_register_operand" "=r,?f")
955 (sign_extend:DI (match_operand:SI 1 "grfr_register_operand" "r,f")))]
959 fsxt.r %0 = %1, %1%B0"
960 [(set_attr "type" "I,F")])
962 ;; Unsigned conversions from a smaller integer to a larger integer
964 (define_insn "zero_extendqidi2"
965 [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
966 (zero_extend:DI (match_operand:QI 1 "gr_nonimmediate_operand" "r,m")))]
971 [(set_attr "type" "I,M")])
973 (define_insn "zero_extendhidi2"
974 [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
975 (zero_extend:DI (match_operand:HI 1 "gr_nonimmediate_operand" "r,m")))]
980 [(set_attr "type" "I,M")])
982 (define_insn "zero_extendsidi2"
983 [(set (match_operand:DI 0 "grfr_register_operand" "=r,r,?f")
985 (match_operand:SI 1 "grfr_nonimmediate_operand" "r,m,f")))]
990 fmix.r %0 = f0, %1%B0"
991 [(set_attr "type" "I,M,F")])
993 ;; Convert between floating point types of different sizes.
995 ;; ??? Optimization opportunity here. Get rid of the insn altogether
996 ;; when we can. Should probably use a scheme like has been proposed
997 ;; for ia32 in dealing with operands that match unary operators. This
998 ;; would let combine merge the thing into adjacent insns.
1000 (define_insn_and_split "extendsfdf2"
1001 [(set (match_operand:DF 0 "grfr_nonimmediate_operand" "=f,f,f,f,m,*r")
1003 (match_operand:SF 1 "grfr_nonimmediate_operand" "0,f,m,*r,f,f")))]
1013 [(set (match_dup 0) (float_extend:DF (match_dup 1)))]
1014 "if (true_regnum (operands[0]) == true_regnum (operands[1])) DONE;"
1015 [(set_attr "type" "F,F,M,M,M,M")])
1017 (define_insn_and_split "extendsftf2"
1018 [(set (match_operand:TF 0 "fr_nonimmediate_operand" "=f,f,f,f,Q")
1020 (match_operand:SF 1 "grfr_nonimmediate_operand" "0,f,Q,*r,f")))]
1029 [(set (match_dup 0) (float_extend:TF (match_dup 1)))]
1030 "if (true_regnum (operands[0]) == true_regnum (operands[1])) DONE;"
1031 [(set_attr "type" "F,F,M,M,M")])
1033 (define_insn_and_split "extenddftf2"
1034 [(set (match_operand:TF 0 "fr_nonimmediate_operand" "=f,f,f,f,Q")
1036 (match_operand:DF 1 "grfr_nonimmediate_operand" "0,f,Q,*r,f")))]
1045 [(set (match_dup 0) (float_extend:TF (match_dup 1)))]
1046 "if (true_regnum (operands[0]) == true_regnum (operands[1])) DONE;"
1047 [(set_attr "type" "F,F,M,M,M")])
1049 (define_insn "truncdfsf2"
1050 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1051 (float_truncate:SF (match_operand:DF 1 "fr_register_operand" "f")))]
1053 "fnorm.s %0 = %1%B0"
1054 [(set_attr "type" "F")])
1056 (define_insn "trunctfsf2"
1057 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1058 (float_truncate:SF (match_operand:TF 1 "fr_register_operand" "f")))]
1060 "fnorm.s %0 = %1%B0"
1061 [(set_attr "type" "F")])
1063 (define_insn "trunctfdf2"
1064 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1065 (float_truncate:DF (match_operand:TF 1 "fr_register_operand" "f")))]
1067 "fnorm.d %0 = %1%B0"
1068 [(set_attr "type" "F")])
1070 ;; Convert between signed integer types and floating point.
1072 (define_insn "floatditf2"
1073 [(set (match_operand:TF 0 "fr_register_operand" "=f")
1074 (float:TF (match_operand:DI 1 "fr_register_operand" "f")))]
1077 [(set_attr "type" "F")])
1079 (define_insn "fix_truncsfdi2"
1080 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1081 (fix:DI (match_operand:SF 1 "fr_register_operand" "f")))]
1083 "fcvt.fx.trunc %0 = %1%B0"
1084 [(set_attr "type" "F")])
1086 (define_insn "fix_truncdfdi2"
1087 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1088 (fix:DI (match_operand:DF 1 "fr_register_operand" "f")))]
1090 "fcvt.fx.trunc %0 = %1%B0"
1091 [(set_attr "type" "F")])
1093 (define_insn "fix_trunctfdi2"
1094 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1095 (fix:DI (match_operand:TF 1 "fr_register_operand" "f")))]
1097 "fcvt.fx.trunc %0 = %1%B0"
1098 [(set_attr "type" "F")])
1100 (define_insn "fix_trunctfdi2_alts"
1101 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1102 (fix:DI (match_operand:TF 1 "fr_register_operand" "f")))
1103 (use (match_operand:SI 2 "const_int_operand" ""))]
1105 "fcvt.fx.trunc.s%2 %0 = %1%B0"
1106 [(set_attr "type" "F")])
1108 ;; Convert between unsigned integer types and floating point.
1110 (define_insn "floatunsdisf2"
1111 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1112 (unsigned_float:SF (match_operand:DI 1 "fr_register_operand" "f")))]
1114 "fcvt.xuf.s %0 = %1%B0"
1115 [(set_attr "type" "F")])
1117 (define_insn "floatunsdidf2"
1118 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1119 (unsigned_float:DF (match_operand:DI 1 "fr_register_operand" "f")))]
1121 "fcvt.xuf.d %0 = %1%B0"
1122 [(set_attr "type" "F")])
1124 (define_insn "floatunsditf2"
1125 [(set (match_operand:TF 0 "fr_register_operand" "=f")
1126 (unsigned_float:TF (match_operand:DI 1 "fr_register_operand" "f")))]
1128 "fcvt.xuf %0 = %1%B0"
1129 [(set_attr "type" "F")])
1131 (define_insn "fixuns_truncsfdi2"
1132 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1133 (unsigned_fix:DI (match_operand:SF 1 "fr_register_operand" "f")))]
1135 "fcvt.fxu.trunc %0 = %1%B0"
1136 [(set_attr "type" "F")])
1138 (define_insn "fixuns_truncdfdi2"
1139 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1140 (unsigned_fix:DI (match_operand:DF 1 "fr_register_operand" "f")))]
1142 "fcvt.fxu.trunc %0 = %1%B0"
1143 [(set_attr "type" "F")])
1145 (define_insn "fixuns_trunctfdi2"
1146 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1147 (unsigned_fix:DI (match_operand:TF 1 "fr_register_operand" "f")))]
1149 "fcvt.fxu.trunc %0 = %1%B0"
1150 [(set_attr "type" "F")])
1152 (define_insn "fixuns_trunctfdi2_alts"
1153 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1154 (unsigned_fix:DI (match_operand:TF 1 "fr_register_operand" "f")))
1155 (use (match_operand:SI 2 "const_int_operand" ""))]
1157 "fcvt.fxu.trunc.s%2 %0 = %1%B0"
1158 [(set_attr "type" "F")])
1160 ;; ::::::::::::::::::::
1162 ;; :: Bit field extraction
1164 ;; ::::::::::::::::::::
1167 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1168 (sign_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
1169 (match_operand:DI 2 "const_int_operand" "n")
1170 (match_operand:DI 3 "const_int_operand" "n")))]
1172 "extr %0 = %1, %3, %2"
1173 [(set_attr "type" "I")])
1175 (define_insn "extzv"
1176 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1177 (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
1178 (match_operand:DI 2 "const_int_operand" "n")
1179 (match_operand:DI 3 "const_int_operand" "n")))]
1181 "extr.u %0 = %1, %3, %2"
1182 [(set_attr "type" "I")])
1184 ;; Insert a bit field.
1185 ;; Can have 3 operands, source1 (inserter), source2 (insertee), dest.
1186 ;; Source1 can be 0 or -1.
1187 ;; Source2 can be 0.
1189 ;; ??? Actual dep instruction is more powerful than what these insv
1190 ;; patterns support. Unfortunately, combine is unable to create patterns
1191 ;; where source2 != dest.
1193 (define_expand "insv"
1194 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "")
1195 (match_operand:DI 1 "const_int_operand" "")
1196 (match_operand:DI 2 "const_int_operand" ""))
1197 (match_operand:DI 3 "nonmemory_operand" ""))]
1201 int width = INTVAL (operands[1]);
1202 int shift = INTVAL (operands[2]);
1204 /* If operand[3] is a constant, and isn't 0 or -1, then load it into a
1206 if (! register_operand (operands[3], DImode)
1207 && operands[3] != const0_rtx && operands[3] != constm1_rtx)
1208 operands[3] = force_reg (DImode, operands[3]);
1210 /* If this is a single dep instruction, we have nothing to do. */
1211 if (! ((register_operand (operands[3], DImode) && width <= 16)
1212 || operands[3] == const0_rtx || operands[3] == constm1_rtx))
1214 /* Check for cases that can be implemented with a mix instruction. */
1215 if (width == 32 && shift == 0)
1217 /* Directly generating the mix4left instruction confuses
1218 optimize_bit_field in function.c. Since this is performing
1219 a useful optimization, we defer generation of the complicated
1220 mix4left RTL to the first splitting phase. */
1221 rtx tmp = gen_reg_rtx (DImode);
1222 emit_insn (gen_shift_mix4left (operands[0], operands[3], tmp));
1225 else if (width == 32 && shift == 32)
1227 emit_insn (gen_mix4right (operands[0], operands[3]));
1231 /* We could handle remaining cases by emitting multiple dep
1234 If we need more than two dep instructions then we lose. A 6
1235 insn sequence mov mask1,mov mask2,shl;;and,and;;or is better than
1236 mov;;dep,shr;;dep,shr;;dep. The former can be executed in 3 cycles,
1237 the latter is 6 cycles on an Itanium (TM) processor, because there is
1238 only one function unit that can execute dep and shr immed.
1240 If we only need two dep instruction, then we still lose.
1241 mov;;dep,shr;;dep is still 4 cycles. Even if we optimize away
1242 the unnecessary mov, this is still undesirable because it will be
1243 hard to optimize, and it creates unnecessary pressure on the I0
1249 /* This code may be useful for other IA-64 processors, so we leave it in
1255 emit_insn (gen_insv (operands[0], GEN_INT (16), GEN_INT (shift),
1259 tmp = gen_reg_rtx (DImode);
1260 emit_insn (gen_lshrdi3 (tmp, operands[3], GEN_INT (16)));
1263 operands[1] = GEN_INT (width);
1264 operands[2] = GEN_INT (shift);
1269 (define_insn "*insv_internal"
1270 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
1271 (match_operand:DI 1 "const_int_operand" "n")
1272 (match_operand:DI 2 "const_int_operand" "n"))
1273 (match_operand:DI 3 "nonmemory_operand" "rP"))]
1274 "(gr_register_operand (operands[3], DImode) && INTVAL (operands[1]) <= 16)
1275 || operands[3] == const0_rtx || operands[3] == constm1_rtx"
1276 "dep %0 = %3, %0, %2, %1"
1277 [(set_attr "type" "I")])
1279 ;; Combine doesn't like to create bitfield insertions into zero.
1280 (define_insn "*depz_internal"
1281 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1282 (and:DI (ashift:DI (match_operand:DI 1 "gr_register_operand" "r")
1283 (match_operand:DI 2 "const_int_operand" "n"))
1284 (match_operand:DI 3 "const_int_operand" "n")))]
1285 "CONST_OK_FOR_M (INTVAL (operands[2]))
1286 && ia64_depz_field_mask (operands[3], operands[2]) > 0"
1289 operands[3] = GEN_INT (ia64_depz_field_mask (operands[3], operands[2]));
1290 return \"%,dep.z %0 = %1, %2, %3\";
1292 [(set_attr "type" "I")])
1294 (define_insn "shift_mix4left"
1295 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
1296 (const_int 32) (const_int 0))
1297 (match_operand:DI 1 "gr_register_operand" "r"))
1298 (clobber (match_operand:DI 2 "gr_register_operand" "=r"))]
1301 [(set_attr "type" "unknown")])
1304 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
1305 (const_int 32) (const_int 0))
1306 (match_operand:DI 1 "register_operand" ""))
1307 (clobber (match_operand:DI 2 "register_operand" ""))]
1309 [(set (match_dup 3) (ashift:DI (match_dup 1) (const_int 32)))
1310 (unspec_volatile [(const_int 0)] 2)
1311 (set (zero_extract:DI (match_dup 0) (const_int 32) (const_int 0))
1312 (lshiftrt:DI (match_dup 3) (const_int 32)))]
1313 "operands[3] = operands[2];")
1316 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
1317 (const_int 32) (const_int 0))
1318 (match_operand:DI 1 "register_operand" ""))
1319 (clobber (match_operand:DI 2 "register_operand" ""))]
1320 "! reload_completed"
1321 [(set (match_dup 3) (ashift:DI (match_dup 1) (const_int 32)))
1322 (set (zero_extract:DI (match_dup 0) (const_int 32) (const_int 0))
1323 (lshiftrt:DI (match_dup 3) (const_int 32)))]
1324 "operands[3] = operands[2];")
1326 (define_insn "*mix4left"
1327 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
1328 (const_int 32) (const_int 0))
1329 (lshiftrt:DI (match_operand:DI 1 "gr_register_operand" "r")
1332 "mix4.l %0 = %0, %r1"
1333 [(set_attr "type" "I")])
1335 (define_insn "mix4right"
1336 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
1337 (const_int 32) (const_int 32))
1338 (match_operand:DI 1 "gr_reg_or_0_operand" "rO"))]
1340 "mix4.r %0 = %r1, %0"
1341 [(set_attr "type" "I")])
1343 ;; This is used by the rotrsi3 pattern.
1345 (define_insn "*mix4right_3op"
1346 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1347 (ior:DI (zero_extend:DI (match_operand:SI 1 "gr_register_operand" "r"))
1348 (ashift:DI (zero_extend:DI
1349 (match_operand:SI 2 "gr_register_operand" "r"))
1352 "mix4.r %0 = %2, %1"
1353 [(set_attr "type" "I")])
1356 ;; ::::::::::::::::::::
1358 ;; :: 16 bit Integer arithmetic
1360 ;; ::::::::::::::::::::
1362 (define_insn "mulhi3"
1363 [(set (match_operand:HI 0 "gr_register_operand" "=r")
1364 (mult:HI (match_operand:HI 1 "gr_register_operand" "r")
1365 (match_operand:HI 2 "gr_register_operand" "r")))]
1367 "pmpy2.r %0 = %1, %2"
1368 [(set_attr "type" "I")])
1371 ;; ::::::::::::::::::::
1373 ;; :: 32 bit Integer arithmetic
1375 ;; ::::::::::::::::::::
1377 (define_insn "addsi3"
1378 [(set (match_operand:SI 0 "gr_register_operand" "=r,r,r")
1379 (plus:SI (match_operand:SI 1 "gr_register_operand" "%r,r,a")
1380 (match_operand:SI 2 "gr_reg_or_22bit_operand" "r,I,J")))]
1386 [(set_attr "type" "A")])
1388 (define_insn "*addsi3_plus1"
1389 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1390 (plus:SI (plus:SI (match_operand:SI 1 "gr_register_operand" "r")
1391 (match_operand:SI 2 "gr_register_operand" "r"))
1394 "add %0 = %1, %2, 1"
1395 [(set_attr "type" "A")])
1397 (define_insn "*addsi3_plus1_alt"
1398 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1399 (plus:SI (mult:SI (match_operand:SI 1 "gr_register_operand" "r")
1403 "add %0 = %1, %1, 1"
1404 [(set_attr "type" "A")])
1406 (define_insn "*addsi3_shladd"
1407 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1408 (plus:SI (mult:SI (match_operand:SI 1 "gr_register_operand" "r")
1409 (match_operand:SI 2 "shladd_operand" "n"))
1410 (match_operand:SI 3 "gr_register_operand" "r")))]
1412 "shladd %0 = %1, %S2, %3"
1413 [(set_attr "type" "A")])
1415 (define_insn "subsi3"
1416 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1417 (minus:SI (match_operand:SI 1 "gr_reg_or_8bit_operand" "rK")
1418 (match_operand:SI 2 "gr_register_operand" "r")))]
1421 [(set_attr "type" "A")])
1423 (define_insn "*subsi3_minus1"
1424 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1425 (plus:SI (not:SI (match_operand:SI 1 "gr_register_operand" "r"))
1426 (match_operand:SI 2 "gr_register_operand" "r")))]
1428 "sub %0 = %2, %1, 1"
1429 [(set_attr "type" "A")])
1431 (define_insn "mulsi3"
1432 [(set (match_operand:SI 0 "fr_register_operand" "=f")
1433 (mult:SI (match_operand:SI 1 "grfr_register_operand" "f")
1434 (match_operand:SI 2 "grfr_register_operand" "f")))]
1436 "xma.l %0 = %1, %2, f0%B0"
1437 [(set_attr "type" "F")])
1439 (define_insn "maddsi4"
1440 [(set (match_operand:SI 0 "fr_register_operand" "=f")
1441 (plus:SI (mult:SI (match_operand:SI 1 "grfr_register_operand" "f")
1442 (match_operand:SI 2 "grfr_register_operand" "f"))
1443 (match_operand:SI 3 "grfr_register_operand" "f")))]
1445 "xma.l %0 = %1, %2, %3%B0"
1446 [(set_attr "type" "F")])
1448 (define_insn "negsi2"
1449 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1450 (neg:SI (match_operand:SI 1 "gr_register_operand" "r")))]
1453 [(set_attr "type" "A")])
1455 (define_expand "abssi2"
1457 (ge:CC (match_operand:SI 1 "gr_register_operand" "") (const_int 0)))
1458 (set (match_operand:SI 0 "gr_register_operand" "")
1459 (if_then_else:SI (eq:CC (match_dup 2) (const_int 0))
1460 (neg:SI (match_dup 1))
1465 operands[2] = gen_reg_rtx (CCmode);
1468 (define_expand "sminsi3"
1470 (ge:CC (match_operand:SI 1 "gr_register_operand" "")
1471 (match_operand:SI 2 "gr_register_operand" "")))
1472 (set (match_operand:SI 0 "gr_register_operand" "")
1473 (if_then_else:SI (ne:CC (match_dup 3) (const_int 0))
1474 (match_dup 2) (match_dup 1)))]
1478 operands[3] = gen_reg_rtx (CCmode);
1481 (define_expand "smaxsi3"
1483 (ge:CC (match_operand:SI 1 "gr_register_operand" "")
1484 (match_operand:SI 2 "gr_register_operand" "")))
1485 (set (match_operand:SI 0 "gr_register_operand" "")
1486 (if_then_else:SI (ne:CC (match_dup 3) (const_int 0))
1487 (match_dup 1) (match_dup 2)))]
1491 operands[3] = gen_reg_rtx (CCmode);
1494 (define_expand "uminsi3"
1496 (geu:CC (match_operand:SI 1 "gr_register_operand" "")
1497 (match_operand:SI 2 "gr_register_operand" "")))
1498 (set (match_operand:SI 0 "gr_register_operand" "")
1499 (if_then_else:SI (ne:CC (match_dup 3) (const_int 0))
1500 (match_dup 2) (match_dup 1)))]
1504 operands[3] = gen_reg_rtx (CCmode);
1507 (define_expand "umaxsi3"
1509 (geu:CC (match_operand:SI 1 "gr_register_operand" "")
1510 (match_operand:SI 2 "gr_register_operand" "")))
1511 (set (match_operand:SI 0 "gr_register_operand" "")
1512 (if_then_else:SI (ne:CC (match_dup 3) (const_int 0))
1513 (match_dup 1) (match_dup 2)))]
1517 operands[3] = gen_reg_rtx (CCmode);
1520 (define_expand "divsi3"
1521 [(set (match_operand:SI 0 "register_operand" "")
1522 (div:SI (match_operand:SI 1 "general_operand" "")
1523 (match_operand:SI 2 "general_operand" "")))]
1527 rtx op1_tf, op2_tf, op0_tf, op0_di, twon34;
1529 op0_tf = gen_reg_rtx (TFmode);
1530 op0_di = gen_reg_rtx (DImode);
1532 if (CONSTANT_P (operands[1]))
1533 operands[1] = force_reg (SImode, operands[1]);
1534 op1_tf = gen_reg_rtx (TFmode);
1535 expand_float (op1_tf, operands[1], 0);
1537 if (CONSTANT_P (operands[2]))
1538 operands[2] = force_reg (SImode, operands[2]);
1539 op2_tf = gen_reg_rtx (TFmode);
1540 expand_float (op2_tf, operands[2], 0);
1544 twon34 = (CONST_DOUBLE_FROM_REAL_VALUE
1545 (REAL_VALUE_FROM_TARGET_SINGLE (0x2e800000), TFmode));
1546 twon34 = force_reg (TFmode, twon34);
1548 twon34 = gen_reg_rtx (TFmode);
1549 convert_move (twon34, force_const_mem (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (REAL_VALUE_FROM_TARGET_SINGLE (0x2e800000), SFmode)), 0);
1552 emit_insn (gen_divsi3_internal (op0_tf, op1_tf, op2_tf, twon34));
1554 emit_insn (gen_fix_trunctfdi2_alts (op0_di, op0_tf, const1_rtx));
1555 emit_move_insn (operands[0], gen_lowpart (SImode, op0_di));
1559 (define_expand "modsi3"
1560 [(set (match_operand:SI 0 "register_operand" "")
1561 (mod:SI (match_operand:SI 1 "general_operand" "")
1562 (match_operand:SI 2 "general_operand" "")))]
1566 rtx op2_neg, op1_di, div;
1568 div = gen_reg_rtx (SImode);
1569 emit_insn (gen_divsi3 (div, operands[1], operands[2]));
1571 op2_neg = expand_unop (SImode, neg_optab, operands[2], NULL_RTX, 0);
1573 /* This is a trick to get us to reuse the value that we're sure to
1574 have already copied to the FP regs. */
1575 op1_di = gen_reg_rtx (DImode);
1576 convert_move (op1_di, operands[1], 0);
1578 emit_insn (gen_maddsi4 (operands[0], div, op2_neg,
1579 gen_lowpart (SImode, op1_di)));
1583 (define_expand "udivsi3"
1584 [(set (match_operand:SI 0 "register_operand" "")
1585 (udiv:SI (match_operand:SI 1 "general_operand" "")
1586 (match_operand:SI 2 "general_operand" "")))]
1590 rtx op1_tf, op2_tf, op0_tf, op0_di, twon34;
1592 op0_tf = gen_reg_rtx (TFmode);
1593 op0_di = gen_reg_rtx (DImode);
1595 if (CONSTANT_P (operands[1]))
1596 operands[1] = force_reg (SImode, operands[1]);
1597 op1_tf = gen_reg_rtx (TFmode);
1598 expand_float (op1_tf, operands[1], 1);
1600 if (CONSTANT_P (operands[2]))
1601 operands[2] = force_reg (SImode, operands[2]);
1602 op2_tf = gen_reg_rtx (TFmode);
1603 expand_float (op2_tf, operands[2], 1);
1607 twon34 = (CONST_DOUBLE_FROM_REAL_VALUE
1608 (REAL_VALUE_FROM_TARGET_SINGLE (0x2e800000), TFmode));
1609 twon34 = force_reg (TFmode, twon34);
1611 twon34 = gen_reg_rtx (TFmode);
1612 convert_move (twon34, force_const_mem (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (REAL_VALUE_FROM_TARGET_SINGLE (0x2e800000), SFmode)), 0);
1615 emit_insn (gen_divsi3_internal (op0_tf, op1_tf, op2_tf, twon34));
1617 emit_insn (gen_fixuns_trunctfdi2_alts (op0_di, op0_tf, const1_rtx));
1618 emit_move_insn (operands[0], gen_lowpart (SImode, op0_di));
1622 (define_expand "umodsi3"
1623 [(set (match_operand:SI 0 "register_operand" "")
1624 (umod:SI (match_operand:SI 1 "general_operand" "")
1625 (match_operand:SI 2 "general_operand" "")))]
1629 rtx op2_neg, op1_di, div;
1631 div = gen_reg_rtx (SImode);
1632 emit_insn (gen_udivsi3 (div, operands[1], operands[2]));
1634 op2_neg = expand_unop (SImode, neg_optab, operands[2], NULL_RTX, 0);
1636 /* This is a trick to get us to reuse the value that we're sure to
1637 have already copied to the FP regs. */
1638 op1_di = gen_reg_rtx (DImode);
1639 convert_move (op1_di, operands[1], 1);
1641 emit_insn (gen_maddsi4 (operands[0], div, op2_neg,
1642 gen_lowpart (SImode, op1_di)));
1646 (define_insn_and_split "divsi3_internal"
1647 [(set (match_operand:TF 0 "fr_register_operand" "=&f")
1648 (float:TF (div:SI (match_operand:TF 1 "fr_register_operand" "f")
1649 (match_operand:TF 2 "fr_register_operand" "f"))))
1650 (clobber (match_scratch:TF 4 "=&f"))
1651 (clobber (match_scratch:TF 5 "=&f"))
1652 (clobber (match_scratch:CC 6 "=c"))
1653 (use (match_operand:TF 3 "fr_register_operand" "f"))]
1656 "&& reload_completed"
1657 [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
1658 (set (match_dup 6) (unspec:CC [(match_dup 1) (match_dup 2)] 5))
1659 (use (const_int 1))])
1660 (cond_exec (ne (match_dup 6) (const_int 0))
1661 (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0)))
1662 (use (const_int 1))]))
1663 (cond_exec (ne (match_dup 6) (const_int 0))
1664 (parallel [(set (match_dup 5)
1665 (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
1667 (use (const_int 1))]))
1668 (cond_exec (ne (match_dup 6) (const_int 0))
1669 (parallel [(set (match_dup 4)
1670 (plus:TF (mult:TF (match_dup 5) (match_dup 4))
1672 (use (const_int 1))]))
1673 (cond_exec (ne (match_dup 6) (const_int 0))
1674 (parallel [(set (match_dup 5)
1675 (plus:TF (mult:TF (match_dup 5) (match_dup 5))
1677 (use (const_int 1))]))
1678 (cond_exec (ne (match_dup 6) (const_int 0))
1679 (parallel [(set (match_dup 0)
1680 (plus:TF (mult:TF (match_dup 5) (match_dup 4))
1682 (use (const_int 1))]))
1684 "operands[7] = CONST1_RTX (TFmode);"
1685 [(set_attr "predicable" "no")])
1687 ;; ::::::::::::::::::::
1689 ;; :: 64 bit Integer arithmetic
1691 ;; ::::::::::::::::::::
1693 (define_insn "adddi3"
1694 [(set (match_operand:DI 0 "gr_register_operand" "=r,r,r")
1695 (plus:DI (match_operand:DI 1 "gr_register_operand" "%r,r,a")
1696 (match_operand:DI 2 "gr_reg_or_22bit_operand" "r,I,J")))]
1702 [(set_attr "type" "A")])
1704 (define_insn "*adddi3_plus1"
1705 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1706 (plus:DI (plus:DI (match_operand:DI 1 "gr_register_operand" "r")
1707 (match_operand:DI 2 "gr_register_operand" "r"))
1710 "add %0 = %1, %2, 1"
1711 [(set_attr "type" "A")])
1713 ;; This has some of the same problems as shladd. We let the shladd
1714 ;; eliminator hack handle it, which results in the 1 being forced into
1715 ;; a register, but not more ugliness here.
1716 (define_insn "*adddi3_plus1_alt"
1717 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1718 (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
1722 "add %0 = %1, %1, 1"
1723 [(set_attr "type" "A")])
1725 (define_insn "subdi3"
1726 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1727 (minus:DI (match_operand:DI 1 "gr_reg_or_8bit_operand" "rK")
1728 (match_operand:DI 2 "gr_register_operand" "r")))]
1731 [(set_attr "type" "A")])
1733 (define_insn "*subdi3_minus1"
1734 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1735 (plus:DI (not:DI (match_operand:DI 1 "gr_register_operand" "r"))
1736 (match_operand:DI 2 "gr_register_operand" "r")))]
1738 "sub %0 = %2, %1, 1"
1739 [(set_attr "type" "A")])
1741 ;; ??? Use grfr instead of fr because of virtual register elimination
1742 ;; and silly test cases multiplying by the frame pointer.
1743 (define_insn "muldi3"
1744 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1745 (mult:DI (match_operand:DI 1 "grfr_register_operand" "f")
1746 (match_operand:DI 2 "grfr_register_operand" "f")))]
1748 "xma.l %0 = %1, %2, f0%B0"
1749 [(set_attr "type" "F")])
1751 ;; ??? If operand 3 is an eliminable reg, then register elimination causes the
1752 ;; same problem that we have with shladd below. Unfortunately, this case is
1753 ;; much harder to fix because the multiply puts the result in an FP register,
1754 ;; but the add needs inputs from a general register. We add a spurious clobber
1755 ;; here so that it will be present just in case register elimination gives us
1756 ;; the funny result.
1758 ;; ??? Maybe validate_changes should try adding match_scratch clobbers?
1760 ;; ??? Maybe we should change how adds are canonicalized.
1762 (define_insn "madddi4"
1763 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1764 (plus:DI (mult:DI (match_operand:DI 1 "grfr_register_operand" "f")
1765 (match_operand:DI 2 "grfr_register_operand" "f"))
1766 (match_operand:DI 3 "grfr_register_operand" "f")))
1767 (clobber (match_scratch:DI 4 "=X"))]
1769 "xma.l %0 = %1, %2, %3%B0"
1770 [(set_attr "type" "F")])
1772 ;; This can be created by register elimination if operand3 of shladd is an
1773 ;; eliminable register or has reg_equiv_constant set.
1775 ;; We have to use nonmemory_operand for operand 4, to ensure that the
1776 ;; validate_changes call inside eliminate_regs will always succeed. If it
1777 ;; doesn't succeed, then this remain a madddi4 pattern, and will be reloaded
1780 (define_insn "*madddi4_elim"
1781 [(set (match_operand:DI 0 "register_operand" "=&r")
1782 (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "f")
1783 (match_operand:DI 2 "register_operand" "f"))
1784 (match_operand:DI 3 "register_operand" "f"))
1785 (match_operand:DI 4 "nonmemory_operand" "rI")))
1786 (clobber (match_scratch:DI 5 "=f"))]
1787 "reload_in_progress"
1789 [(set_attr "type" "unknown")])
1791 ;; ??? Need to emit an instruction group barrier here because this gets split
1795 [(set (match_operand:DI 0 "register_operand" "")
1796 (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
1797 (match_operand:DI 2 "register_operand" ""))
1798 (match_operand:DI 3 "register_operand" ""))
1799 (match_operand:DI 4 "gr_reg_or_14bit_operand" "")))
1800 (clobber (match_scratch:DI 5 ""))]
1802 [(parallel [(set (match_dup 5) (plus:DI (mult:DI (match_dup 1) (match_dup 2))
1804 (clobber (match_dup 0))])
1805 (unspec_volatile [(const_int 0)] 2)
1806 (set (match_dup 0) (match_dup 5))
1807 (unspec_volatile [(const_int 0)] 2)
1808 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
1811 ;; ??? There are highpart multiply and add instructions, but we have no way
1812 ;; to generate them.
1814 (define_insn "smuldi3_highpart"
1815 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1818 (mult:TI (sign_extend:TI
1819 (match_operand:DI 1 "fr_register_operand" "f"))
1821 (match_operand:DI 2 "fr_register_operand" "f")))
1824 "xma.h %0 = %1, %2, f0%B0"
1825 [(set_attr "type" "F")])
1827 (define_insn "umuldi3_highpart"
1828 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1831 (mult:TI (zero_extend:TI
1832 (match_operand:DI 1 "fr_register_operand" "f"))
1834 (match_operand:DI 2 "fr_register_operand" "f")))
1837 "xma.hu %0 = %1, %2, f0%B0"
1838 [(set_attr "type" "F")])
1840 (define_insn "negdi2"
1841 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1842 (neg:DI (match_operand:DI 1 "gr_register_operand" "r")))]
1845 [(set_attr "type" "A")])
1847 (define_expand "absdi2"
1849 (ge:CC (match_operand:DI 1 "gr_register_operand" "") (const_int 0)))
1850 (set (match_operand:DI 0 "gr_register_operand" "")
1851 (if_then_else:DI (eq:CC (match_dup 2) (const_int 0))
1852 (neg:DI (match_dup 1))
1857 operands[2] = gen_reg_rtx (CCmode);
1860 (define_expand "smindi3"
1862 (ge:CC (match_operand:DI 1 "gr_register_operand" "")
1863 (match_operand:DI 2 "gr_register_operand" "")))
1864 (set (match_operand:DI 0 "gr_register_operand" "")
1865 (if_then_else:DI (ne:CC (match_dup 3) (const_int 0))
1866 (match_dup 2) (match_dup 1)))]
1870 operands[3] = gen_reg_rtx (CCmode);
1873 (define_expand "smaxdi3"
1875 (ge:CC (match_operand:DI 1 "gr_register_operand" "")
1876 (match_operand:DI 2 "gr_register_operand" "")))
1877 (set (match_operand:DI 0 "gr_register_operand" "")
1878 (if_then_else:DI (ne:CC (match_dup 3) (const_int 0))
1879 (match_dup 1) (match_dup 2)))]
1883 operands[3] = gen_reg_rtx (CCmode);
1886 (define_expand "umindi3"
1888 (geu:CC (match_operand:DI 1 "gr_register_operand" "")
1889 (match_operand:DI 2 "gr_register_operand" "")))
1890 (set (match_operand:DI 0 "gr_register_operand" "")
1891 (if_then_else:DI (ne:CC (match_dup 3) (const_int 0))
1892 (match_dup 2) (match_dup 1)))]
1896 operands[3] = gen_reg_rtx (CCmode);
1899 (define_expand "umaxdi3"
1901 (geu:CC (match_operand:DI 1 "gr_register_operand" "")
1902 (match_operand:DI 2 "gr_register_operand" "")))
1903 (set (match_operand:DI 0 "gr_register_operand" "")
1904 (if_then_else:DI (ne:CC (match_dup 3) (const_int 0))
1905 (match_dup 1) (match_dup 2)))]
1909 operands[3] = gen_reg_rtx (CCmode);
1912 (define_expand "ffsdi2"
1914 (eq:CC (match_operand:DI 1 "gr_register_operand" "") (const_int 0)))
1915 (set (match_dup 2) (plus:DI (match_dup 1) (const_int -1)))
1916 (set (match_dup 5) (const_int 0))
1917 (set (match_dup 3) (xor:DI (match_dup 1) (match_dup 2)))
1918 (set (match_dup 4) (unspec:DI [(match_dup 3)] 8))
1919 (set (match_operand:DI 0 "gr_register_operand" "")
1920 (if_then_else:DI (ne:CC (match_dup 6) (const_int 0))
1921 (match_dup 5) (match_dup 4)))]
1925 operands[2] = gen_reg_rtx (DImode);
1926 operands[3] = gen_reg_rtx (DImode);
1927 operands[4] = gen_reg_rtx (DImode);
1928 operands[5] = gen_reg_rtx (DImode);
1929 operands[6] = gen_reg_rtx (CCmode);
1932 (define_insn "*popcnt"
1933 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1934 (unspec:DI [(match_operand:DI 1 "gr_register_operand" "r")] 8))]
1937 [(set_attr "type" "I")])
1939 (define_expand "divdi3"
1940 [(set (match_operand:DI 0 "register_operand" "")
1941 (div:DI (match_operand:DI 1 "general_operand" "")
1942 (match_operand:DI 2 "general_operand" "")))]
1946 rtx op1_tf, op2_tf, op0_tf;
1948 op0_tf = gen_reg_rtx (TFmode);
1950 if (CONSTANT_P (operands[1]))
1951 operands[1] = force_reg (DImode, operands[1]);
1952 op1_tf = gen_reg_rtx (TFmode);
1953 expand_float (op1_tf, operands[1], 0);
1955 if (CONSTANT_P (operands[2]))
1956 operands[2] = force_reg (DImode, operands[2]);
1957 op2_tf = gen_reg_rtx (TFmode);
1958 expand_float (op2_tf, operands[2], 0);
1960 if (TARGET_INLINE_DIV_LAT)
1961 emit_insn (gen_divdi3_internal_lat (op0_tf, op1_tf, op2_tf));
1963 emit_insn (gen_divdi3_internal_thr (op0_tf, op1_tf, op2_tf));
1965 emit_insn (gen_fix_trunctfdi2_alts (operands[0], op0_tf, const1_rtx));
1969 (define_expand "moddi3"
1970 [(set (match_operand:DI 0 "register_operand" "")
1971 (mod:SI (match_operand:DI 1 "general_operand" "")
1972 (match_operand:DI 2 "general_operand" "")))]
1978 div = gen_reg_rtx (DImode);
1979 emit_insn (gen_divdi3 (div, operands[1], operands[2]));
1981 op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0);
1983 emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1]));
1987 (define_expand "udivdi3"
1988 [(set (match_operand:DI 0 "register_operand" "")
1989 (udiv:DI (match_operand:DI 1 "general_operand" "")
1990 (match_operand:DI 2 "general_operand" "")))]
1994 rtx op1_tf, op2_tf, op0_tf;
1996 op0_tf = gen_reg_rtx (TFmode);
1998 if (CONSTANT_P (operands[1]))
1999 operands[1] = force_reg (DImode, operands[1]);
2000 op1_tf = gen_reg_rtx (TFmode);
2001 expand_float (op1_tf, operands[1], 1);
2003 if (CONSTANT_P (operands[2]))
2004 operands[2] = force_reg (DImode, operands[2]);
2005 op2_tf = gen_reg_rtx (TFmode);
2006 expand_float (op2_tf, operands[2], 1);
2008 if (TARGET_INLINE_DIV_LAT)
2009 emit_insn (gen_divdi3_internal_lat (op0_tf, op1_tf, op2_tf));
2011 emit_insn (gen_divdi3_internal_thr (op0_tf, op1_tf, op2_tf));
2013 emit_insn (gen_fixuns_trunctfdi2_alts (operands[0], op0_tf, const1_rtx));
2017 (define_expand "umoddi3"
2018 [(set (match_operand:DI 0 "register_operand" "")
2019 (umod:DI (match_operand:DI 1 "general_operand" "")
2020 (match_operand:DI 2 "general_operand" "")))]
2026 div = gen_reg_rtx (DImode);
2027 emit_insn (gen_udivdi3 (div, operands[1], operands[2]));
2029 op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0);
2031 emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1]));
2035 (define_insn_and_split "divdi3_internal_lat"
2036 [(set (match_operand:TF 0 "fr_register_operand" "=&f")
2037 (float:TF (div:SI (match_operand:TF 1 "fr_register_operand" "f")
2038 (match_operand:TF 2 "fr_register_operand" "f"))))
2039 (clobber (match_scratch:TF 3 "=&f"))
2040 (clobber (match_scratch:TF 4 "=&f"))
2041 (clobber (match_scratch:TF 5 "=&f"))
2042 (clobber (match_scratch:CC 6 "=c"))]
2043 "TARGET_INLINE_DIV_LAT"
2045 "&& reload_completed"
2046 [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
2047 (set (match_dup 6) (unspec:CC [(match_dup 1) (match_dup 2)] 5))
2048 (use (const_int 1))])
2049 (cond_exec (ne (match_dup 6) (const_int 0))
2050 (parallel [(set (match_dup 3)
2051 (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
2053 (use (const_int 1))]))
2054 (cond_exec (ne (match_dup 6) (const_int 0))
2055 (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0)))
2056 (use (const_int 1))]))
2057 (cond_exec (ne (match_dup 6) (const_int 0))
2058 (parallel [(set (match_dup 5) (mult:TF (match_dup 3) (match_dup 3)))
2059 (use (const_int 1))]))
2060 (cond_exec (ne (match_dup 6) (const_int 0))
2061 (parallel [(set (match_dup 4)
2062 (plus:TF (mult:TF (match_dup 3) (match_dup 4))
2064 (use (const_int 1))]))
2065 (cond_exec (ne (match_dup 6) (const_int 0))
2066 (parallel [(set (match_dup 0)
2067 (plus:TF (mult:TF (match_dup 3) (match_dup 0))
2069 (use (const_int 1))]))
2070 (cond_exec (ne (match_dup 6) (const_int 0))
2071 (parallel [(set (match_dup 3)
2072 (plus:TF (mult:TF (match_dup 5) (match_dup 4))
2074 (use (const_int 1))]))
2075 (cond_exec (ne (match_dup 6) (const_int 0))
2076 (parallel [(set (match_dup 0)
2077 (plus:TF (mult:TF (match_dup 5) (match_dup 0))
2079 (use (const_int 1))]))
2080 (cond_exec (ne (match_dup 6) (const_int 0))
2081 (parallel [(set (match_dup 4)
2082 (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
2084 (use (const_int 1))]))
2085 (cond_exec (ne (match_dup 6) (const_int 0))
2086 (parallel [(set (match_dup 0)
2087 (plus:TF (mult:TF (match_dup 4) (match_dup 0))
2089 (use (const_int 1))]))
2091 "operands[7] = CONST1_RTX (TFmode);"
2092 [(set_attr "predicable" "no")])
2094 (define_insn_and_split "divdi3_internal_thr"
2095 [(set (match_operand:TF 0 "fr_register_operand" "=&f")
2096 (float:TF (div:SI (match_operand:TF 1 "fr_register_operand" "f")
2097 (match_operand:TF 2 "fr_register_operand" "f"))))
2098 (clobber (match_scratch:TF 3 "=&f"))
2099 (clobber (match_scratch:TF 4 "=f"))
2100 (clobber (match_scratch:CC 5 "=c"))]
2101 "TARGET_INLINE_DIV_THR"
2103 "&& reload_completed"
2104 [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
2105 (set (match_dup 5) (unspec:CC [(match_dup 1) (match_dup 2)] 5))
2106 (use (const_int 1))])
2107 (cond_exec (ne (match_dup 5) (const_int 0))
2108 (parallel [(set (match_dup 3)
2109 (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
2111 (use (const_int 1))]))
2112 (cond_exec (ne (match_dup 5) (const_int 0))
2113 (parallel [(set (match_dup 0)
2114 (plus:TF (mult:TF (match_dup 3) (match_dup 0))
2116 (use (const_int 1))]))
2117 (cond_exec (ne (match_dup 5) (const_int 0))
2118 (parallel [(set (match_dup 3) (mult:TF (match_dup 3) (match_dup 3)))
2119 (use (const_int 1))]))
2120 (cond_exec (ne (match_dup 5) (const_int 0))
2121 (parallel [(set (match_dup 0)
2122 (plus:TF (mult:TF (match_dup 3) (match_dup 0))
2124 (use (const_int 1))]))
2125 (cond_exec (ne (match_dup 5) (const_int 0))
2126 (parallel [(set (match_dup 3) (mult:TF (match_dup 0) (match_dup 1)))
2127 (use (const_int 1))]))
2128 (cond_exec (ne (match_dup 5) (const_int 0))
2129 (parallel [(set (match_dup 4)
2130 (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
2132 (use (const_int 1))]))
2133 (cond_exec (ne (match_dup 5) (const_int 0))
2134 (parallel [(set (match_dup 0)
2135 (plus:TF (mult:TF (match_dup 4) (match_dup 0))
2137 (use (const_int 1))]))
2139 "operands[6] = CONST1_RTX (TFmode);"
2140 [(set_attr "predicable" "no")])
2142 ;; ::::::::::::::::::::
2144 ;; :: 32 bit floating point arithmetic
2146 ;; ::::::::::::::::::::
2148 (define_insn "addsf3"
2149 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2150 (plus:SF (match_operand:SF 1 "fr_register_operand" "%f")
2151 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
2153 "fadd.s %0 = %1, %F2%B0"
2154 [(set_attr "type" "F")])
2156 (define_insn "subsf3"
2157 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2158 (minus:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
2159 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
2161 "fsub.s %0 = %F1, %F2%B0"
2162 [(set_attr "type" "F")])
2164 (define_insn "mulsf3"
2165 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2166 (mult:SF (match_operand:SF 1 "fr_register_operand" "%f")
2167 (match_operand:SF 2 "fr_register_operand" "f")))]
2169 "fmpy.s %0 = %1, %2%B0"
2170 [(set_attr "type" "F")])
2172 (define_insn "abssf2"
2173 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2174 (abs:SF (match_operand:SF 1 "fr_register_operand" "f")))]
2177 [(set_attr "type" "F")])
2179 (define_insn "negsf2"
2180 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2181 (neg:SF (match_operand:SF 1 "fr_register_operand" "f")))]
2184 [(set_attr "type" "F")])
2186 (define_insn "*nabssf2"
2187 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2188 (neg:SF (abs:SF (match_operand:SF 1 "fr_register_operand" "f"))))]
2190 "fnegabs %0 = %1%B0"
2191 [(set_attr "type" "F")])
2193 (define_insn "minsf3"
2194 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2195 (smin:SF (match_operand:SF 1 "fr_register_operand" "f")
2196 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
2198 "fmin %0 = %1, %F2%B0"
2199 [(set_attr "type" "F")])
2201 (define_insn "maxsf3"
2202 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2203 (smax:SF (match_operand:SF 1 "fr_register_operand" "f")
2204 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
2206 "fmax %0 = %1, %F2%B0"
2207 [(set_attr "type" "F")])
2209 (define_insn "*maddsf4"
2210 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2211 (plus:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
2212 (match_operand:SF 2 "fr_register_operand" "f"))
2213 (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
2215 "fma.s %0 = %1, %2, %F3%B0"
2216 [(set_attr "type" "F")])
2218 (define_insn "*msubsf4"
2219 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2220 (minus:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
2221 (match_operand:SF 2 "fr_register_operand" "f"))
2222 (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
2224 "fms.s %0 = %1, %2, %F3%B0"
2225 [(set_attr "type" "F")])
2227 (define_insn "*nmulsf3"
2228 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2229 (neg:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
2230 (match_operand:SF 2 "fr_register_operand" "f"))))]
2232 "fnmpy.s %0 = %1, %2%B0"
2233 [(set_attr "type" "F")])
2235 ;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
2237 (define_insn "*nmaddsf4"
2238 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2239 (plus:SF (neg:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
2240 (match_operand:SF 2 "fr_register_operand" "f")))
2241 (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
2243 "fnma.s %0 = %1, %2, %F3%B0"
2244 [(set_attr "type" "F")])
2247 ;; ::::::::::::::::::::
2249 ;; :: 64 bit floating point arithmetic
2251 ;; ::::::::::::::::::::
2253 (define_insn "adddf3"
2254 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2255 (plus:DF (match_operand:DF 1 "fr_register_operand" "%f")
2256 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
2258 "fadd.d %0 = %1, %F2%B0"
2259 [(set_attr "type" "F")])
2261 (define_insn "subdf3"
2262 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2263 (minus:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
2264 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
2266 "fsub.d %0 = %F1, %F2%B0"
2267 [(set_attr "type" "F")])
2269 (define_insn "muldf3"
2270 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2271 (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
2272 (match_operand:DF 2 "fr_register_operand" "f")))]
2274 "fmpy.d %0 = %1, %2%B0"
2275 [(set_attr "type" "F")])
2277 (define_insn "absdf2"
2278 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2279 (abs:DF (match_operand:DF 1 "fr_register_operand" "f")))]
2282 [(set_attr "type" "F")])
2284 (define_insn "negdf2"
2285 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2286 (neg:DF (match_operand:DF 1 "fr_register_operand" "f")))]
2289 [(set_attr "type" "F")])
2291 (define_insn "*nabsdf2"
2292 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2293 (neg:DF (abs:DF (match_operand:DF 1 "fr_register_operand" "f"))))]
2295 "fnegabs %0 = %1%B0"
2296 [(set_attr "type" "F")])
2298 (define_insn "mindf3"
2299 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2300 (smin:DF (match_operand:DF 1 "fr_register_operand" "f")
2301 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
2303 "fmin %0 = %1, %F2%B0"
2304 [(set_attr "type" "F")])
2306 (define_insn "maxdf3"
2307 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2308 (smax:DF (match_operand:DF 1 "fr_register_operand" "f")
2309 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
2311 "fmax %0 = %1, %F2%B0"
2312 [(set_attr "type" "F")])
2314 (define_insn "*madddf4"
2315 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2316 (plus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
2317 (match_operand:DF 2 "fr_register_operand" "f"))
2318 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
2320 "fma.d %0 = %1, %2, %F3%B0"
2321 [(set_attr "type" "F")])
2323 (define_insn "*msubdf4"
2324 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2325 (minus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
2326 (match_operand:DF 2 "fr_register_operand" "f"))
2327 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
2329 "fms.d %0 = %1, %2, %F3%B0"
2330 [(set_attr "type" "F")])
2332 (define_insn "*nmuldf3"
2333 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2334 (neg:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
2335 (match_operand:DF 2 "fr_register_operand" "f"))))]
2337 "fnmpy.d %0 = %1, %2%B0"
2338 [(set_attr "type" "F")])
2340 ;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
2342 (define_insn "*nmadddf4"
2343 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2344 (plus:DF (neg:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
2345 (match_operand:DF 2 "fr_register_operand" "f")))
2346 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
2348 "fnma.d %0 = %1, %2, %F3%B0"
2349 [(set_attr "type" "F")])
2351 ;; ::::::::::::::::::::
2353 ;; :: 80 bit floating point arithmetic
2355 ;; ::::::::::::::::::::
2357 (define_insn "addtf3"
2358 [(set (match_operand:TF 0 "fr_register_operand" "=f")
2359 (plus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
2360 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
2362 "fadd %0 = %F1, %F2%B0"
2363 [(set_attr "type" "F")])
2365 (define_insn "subtf3"
2366 [(set (match_operand:TF 0 "fr_register_operand" "=f")
2367 (minus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
2368 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
2370 "fsub %0 = %F1, %F2%B0"
2371 [(set_attr "type" "F")])
2373 (define_insn "multf3"
2374 [(set (match_operand:TF 0 "fr_register_operand" "=f")
2375 (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
2376 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
2378 "fmpy %0 = %F1, %F2%B0"
2379 [(set_attr "type" "F")])
2381 (define_insn "*multf3_alts"
2382 [(set (match_operand:TF 0 "fr_register_operand" "=f")
2383 (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
2384 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
2385 (use (match_operand:SI 3 "const_int_operand" ""))]
2387 "fmpy.s%3 %0 = %F1, %F2%B0"
2388 [(set_attr "type" "F")])
2390 (define_insn "abstf2"
2391 [(set (match_operand:TF 0 "fr_register_operand" "=f")
2392 (abs:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")))]
2395 [(set_attr "type" "F")])
2397 (define_insn "negtf2"
2398 [(set (match_operand:TF 0 "fr_register_operand" "=f")
2399 (neg:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")))]
2402 [(set_attr "type" "F")])
2404 (define_insn "*nabstf2"
2405 [(set (match_operand:TF 0 "fr_register_operand" "=f")
2406 (neg:TF (abs:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG"))))]
2408 "fnegabs %0 = %F1%B0"
2409 [(set_attr "type" "F")])
2411 (define_insn "mintf3"
2412 [(set (match_operand:TF 0 "fr_register_operand" "=f")
2413 (smin:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
2414 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
2416 "fmin %0 = %F1, %F2%B0"
2417 [(set_attr "type" "F")])
2419 (define_insn "maxtf3"
2420 [(set (match_operand:TF 0 "fr_register_operand" "=f")
2421 (smax:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
2422 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
2424 "fmax %0 = %F1, %F2%B0"
2425 [(set_attr "type" "F")])
2427 (define_insn "*maddtf4"
2428 [(set (match_operand:TF 0 "fr_register_operand" "=f")
2429 (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
2430 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
2431 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))]
2433 "fma %0 = %F1, %F2, %F3%B0"
2434 [(set_attr "type" "F")])
2436 (define_insn "*maddtf4_alts"
2437 [(set (match_operand:TF 0 "fr_register_operand" "=f")
2438 (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
2439 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
2440 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))
2441 (use (match_operand:SI 4 "const_int_operand" ""))]
2443 "fma.s%4 %0 = %F1, %F2, %F3%B0"
2444 [(set_attr "type" "F")])
2446 (define_insn "*msubtf4"
2447 [(set (match_operand:TF 0 "fr_register_operand" "=f")
2448 (minus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
2449 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
2450 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))]
2452 "fms %0 = %F1, %F2, %F3%B0"
2453 [(set_attr "type" "F")])
2455 (define_insn "*nmultf3"
2456 [(set (match_operand:TF 0 "fr_register_operand" "=f")
2457 (neg:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
2458 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
2460 "fnmpy %0 = %F1, %F2%B0"
2461 [(set_attr "type" "F")])
2463 ;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
2465 (define_insn "*nmaddtf4"
2466 [(set (match_operand:TF 0 "fr_register_operand" "=f")
2467 (plus:TF (neg:TF (mult:TF
2468 (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
2469 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
2470 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))]
2472 "fnma %0 = %F1, %F2, %F3%B0"
2473 [(set_attr "type" "F")])
2475 (define_insn "*nmaddtf4_alts"
2476 [(set (match_operand:TF 0 "fr_register_operand" "=f")
2477 (plus:TF (neg:TF (mult:TF
2478 (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
2479 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
2480 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))
2481 (use (match_operand:SI 4 "const_int_operand" ""))]
2483 "fnma.s%4 %0 = %F1, %F2, %F3%B0"
2484 [(set_attr "type" "F")])
2486 (define_insn "*recip_approx"
2487 [(set (match_operand:TF 0 "fr_register_operand" "=f")
2488 (div:TF (const_int 1)
2489 (match_operand:TF 3 "fr_register_operand" "f")))
2490 (set (match_operand:CC 1 "register_operand" "=c")
2491 (unspec:CC [(match_operand:TF 2 "fr_register_operand" "f")
2493 (use (match_operand:SI 4 "const_int_operand" ""))]
2495 "frcpa.s%4 %0, %1 = %2, %3"
2496 [(set_attr "type" "F")])
2498 ;; ::::::::::::::::::::
2500 ;; :: 32 bit Integer Shifts and Rotates
2502 ;; ::::::::::::::::::::
2504 (define_expand "ashlsi3"
2505 [(set (match_operand:SI 0 "gr_register_operand" "")
2506 (ashift:SI (match_operand:SI 1 "gr_register_operand" "")
2507 (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
2511 if (GET_CODE (operands[2]) != CONST_INT)
2513 /* Why oh why didn't Intel arrange for SHIFT_COUNT_TRUNCATED? Now
2514 we've got to get rid of stray bits outside the SImode register. */
2515 rtx subshift = gen_reg_rtx (DImode);
2516 emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
2517 operands[2] = subshift;
2521 (define_insn "*ashlsi3_internal"
2522 [(set (match_operand:SI 0 "gr_register_operand" "=r,r,r")
2523 (ashift:SI (match_operand:SI 1 "gr_register_operand" "r,r,r")
2524 (match_operand:DI 2 "gr_reg_or_5bit_operand" "R,n,r")))]
2527 shladd %0 = %1, %2, r0
2528 dep.z %0 = %1, %2, %E2
2530 [(set_attr "type" "A,I,I")])
2532 (define_expand "ashrsi3"
2533 [(set (match_operand:SI 0 "gr_register_operand" "")
2534 (ashiftrt:SI (match_operand:SI 1 "gr_register_operand" "")
2535 (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
2539 rtx subtarget = gen_reg_rtx (DImode);
2540 if (GET_CODE (operands[2]) == CONST_INT)
2541 emit_insn (gen_extv (subtarget, gen_lowpart (DImode, operands[1]),
2542 GEN_INT (32 - INTVAL (operands[2])), operands[2]));
2545 rtx subshift = gen_reg_rtx (DImode);
2546 emit_insn (gen_extendsidi2 (subtarget, operands[1]));
2547 emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
2548 emit_insn (gen_ashrdi3 (subtarget, subtarget, subshift));
2550 emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget);
2554 (define_expand "lshrsi3"
2555 [(set (match_operand:SI 0 "gr_register_operand" "")
2556 (lshiftrt:SI (match_operand:SI 1 "gr_register_operand" "")
2557 (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
2561 rtx subtarget = gen_reg_rtx (DImode);
2562 if (GET_CODE (operands[2]) == CONST_INT)
2563 emit_insn (gen_extzv (subtarget, gen_lowpart (DImode, operands[1]),
2564 GEN_INT (32 - INTVAL (operands[2])), operands[2]));
2567 rtx subshift = gen_reg_rtx (DImode);
2568 emit_insn (gen_zero_extendsidi2 (subtarget, operands[1]));
2569 emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
2570 emit_insn (gen_lshrdi3 (subtarget, subtarget, subshift));
2572 emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget);
2576 ;; Use mix4.r/shr to implement rotrsi3. We only get 32 bits of valid result
2577 ;; here, instead of 64 like the patterns above.
2579 (define_expand "rotrsi3"
2581 (ior:DI (zero_extend:DI (match_operand:SI 1 "gr_register_operand" ""))
2582 (ashift:DI (zero_extend:DI (match_dup 1)) (const_int 32))))
2584 (lshiftrt:DI (match_dup 3)
2585 (match_operand:DI 2 "nonmemory_operand" "")))
2586 (set (match_operand:SI 0 "gr_register_operand" "") (match_dup 4))]
2590 if (! shift_32bit_count_operand (operands[2], SImode))
2592 operands[3] = gen_reg_rtx (DImode);
2593 operands[4] = gen_lowpart (SImode, operands[3]);
2596 ;; ::::::::::::::::::::
2598 ;; :: 64 bit Integer Shifts and Rotates
2600 ;; ::::::::::::::::::::
2602 (define_insn "ashldi3"
2603 [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
2604 (ashift:DI (match_operand:DI 1 "gr_register_operand" "r,r")
2605 (match_operand:DI 2 "gr_reg_or_6bit_operand" "R,rM")))]
2608 shladd %0 = %1, %2, r0
2610 [(set_attr "type" "A,I")])
2612 ;; ??? Maybe combine this with the multiply and add instruction?
2614 (define_insn "*shladd"
2615 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2616 (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
2617 (match_operand:DI 2 "shladd_operand" "n"))
2618 (match_operand:DI 3 "gr_register_operand" "r")))]
2620 "shladd %0 = %1, %S2, %3"
2621 [(set_attr "type" "A")])
2623 ;; This can be created by register elimination if operand3 of shladd is an
2624 ;; eliminable register or has reg_equiv_constant set.
2626 ;; We have to use nonmemory_operand for operand 4, to ensure that the
2627 ;; validate_changes call inside eliminate_regs will always succeed. If it
2628 ;; doesn't succeed, then this remain a shladd pattern, and will be reloaded
2631 (define_insn_and_split "*shladd_elim"
2632 [(set (match_operand:DI 0 "gr_register_operand" "=&r")
2633 (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
2634 (match_operand:DI 2 "shladd_operand" "n"))
2635 (match_operand:DI 3 "nonmemory_operand" "r"))
2636 (match_operand:DI 4 "nonmemory_operand" "rI")))]
2637 "reload_in_progress"
2640 [(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (match_dup 2))
2642 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
2644 [(set_attr "type" "unknown")])
2646 (define_insn "ashrdi3"
2647 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2648 (ashiftrt:DI (match_operand:DI 1 "gr_register_operand" "r")
2649 (match_operand:DI 2 "gr_reg_or_6bit_operand" "rM")))]
2652 [(set_attr "type" "I")])
2654 (define_insn "lshrdi3"
2655 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2656 (lshiftrt:DI (match_operand:DI 1 "gr_register_operand" "r")
2657 (match_operand:DI 2 "gr_reg_or_6bit_operand" "rM")))]
2660 [(set_attr "type" "I")])
2662 ;; Using a predicate that accepts only constants doesn't work, because optabs
2663 ;; will load the operand into a register and call the pattern if the predicate
2664 ;; did not accept it on the first try. So we use nonmemory_operand and then
2665 ;; verify that we have an appropriate constant in the expander.
2667 (define_expand "rotrdi3"
2668 [(set (match_operand:DI 0 "gr_register_operand" "")
2669 (rotatert:DI (match_operand:DI 1 "gr_register_operand" "")
2670 (match_operand:DI 2 "nonmemory_operand" "")))]
2674 if (! shift_count_operand (operands[2], DImode))
2678 (define_insn "*rotrdi3_internal"
2679 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2680 (rotatert:DI (match_operand:DI 1 "gr_register_operand" "r")
2681 (match_operand:DI 2 "shift_count_operand" "M")))]
2683 "shrp %0 = %1, %1, %2"
2684 [(set_attr "type" "I")])
2687 ;; ::::::::::::::::::::
2689 ;; :: 32 bit Integer Logical operations
2691 ;; ::::::::::::::::::::
2693 ;; We don't seem to need any other 32-bit logical operations, because gcc
2694 ;; generates zero-extend;zero-extend;DImode-op, which combine optimizes to
2695 ;; DImode-op;zero-extend, and then we can optimize away the zero-extend.
2696 ;; This doesn't work for unary logical operations, because we don't call
2697 ;; apply_distributive_law for them.
2699 ;; ??? Likewise, this doesn't work for andnot, which isn't handled by
2700 ;; apply_distributive_law. We get inefficient code for
2701 ;; int sub4 (int i, int j) { return i & ~j; }
2702 ;; We could convert (and (not (sign_extend A)) (sign_extend B)) to
2703 ;; (zero_extend (and (not A) B)) in combine.
2704 ;; Or maybe fix this by adding andsi3/iorsi3/xorsi3 patterns like the
2705 ;; one_cmplsi2 pattern.
2707 (define_insn "one_cmplsi2"
2708 [(set (match_operand:SI 0 "gr_register_operand" "=r")
2709 (not:SI (match_operand:SI 1 "gr_register_operand" "r")))]
2712 [(set_attr "type" "A")])
2714 ;; ::::::::::::::::::::
2716 ;; :: 64 bit Integer Logical operations
2718 ;; ::::::::::::::::::::
2720 (define_insn "anddi3"
2721 [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
2722 (and:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
2723 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
2727 fand %0 = %2, %1%B0"
2728 [(set_attr "type" "A,F")])
2730 (define_insn "*andnot"
2731 [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
2732 (and:DI (not:DI (match_operand:DI 1 "grfr_register_operand" "r,*f"))
2733 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
2737 fandcm %0 = %2, %1%B0"
2738 [(set_attr "type" "A,F")])
2740 (define_insn "iordi3"
2741 [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
2742 (ior:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
2743 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
2748 [(set_attr "type" "A,F")])
2750 (define_insn "xordi3"
2751 [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
2752 (xor:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
2753 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
2757 fxor %0 = %2, %1%B0"
2758 [(set_attr "type" "A,F")])
2760 (define_insn "one_cmpldi2"
2761 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2762 (not:DI (match_operand:DI 1 "gr_register_operand" "r")))]
2765 [(set_attr "type" "A")])
2767 ;; ::::::::::::::::::::
2771 ;; ::::::::::::::::::::
2773 (define_expand "cmpsi"
2775 (compare (match_operand:SI 0 "gr_register_operand" "")
2776 (match_operand:SI 1 "gr_reg_or_8bit_and_adjusted_operand" "")))]
2780 ia64_compare_op0 = operands[0];
2781 ia64_compare_op1 = operands[1];
2785 (define_expand "cmpdi"
2787 (compare (match_operand:DI 0 "gr_register_operand" "")
2788 (match_operand:DI 1 "gr_reg_or_8bit_and_adjusted_operand" "")))]
2792 ia64_compare_op0 = operands[0];
2793 ia64_compare_op1 = operands[1];
2797 (define_expand "cmpsf"
2799 (compare (match_operand:SF 0 "fr_reg_or_fp01_operand" "")
2800 (match_operand:SF 1 "fr_reg_or_fp01_operand" "")))]
2804 ia64_compare_op0 = operands[0];
2805 ia64_compare_op1 = operands[1];
2809 (define_expand "cmpdf"
2811 (compare (match_operand:DF 0 "fr_reg_or_fp01_operand" "")
2812 (match_operand:DF 1 "fr_reg_or_fp01_operand" "")))]
2816 ia64_compare_op0 = operands[0];
2817 ia64_compare_op1 = operands[1];
2821 (define_expand "cmptf"
2823 (compare (match_operand:TF 0 "tfreg_or_fp01_operand" "")
2824 (match_operand:TF 1 "tfreg_or_fp01_operand" "")))]
2828 ia64_compare_op0 = operands[0];
2829 ia64_compare_op1 = operands[1];
2833 (define_insn "*cmpsi_normal"
2834 [(set (match_operand:CC 0 "register_operand" "=c")
2835 (match_operator:CC 1 "normal_comparison_operator"
2836 [(match_operand:SI 2 "gr_register_operand" "r")
2837 (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))]
2839 "cmp4.%C1 %0, %I0 = %3, %2"
2840 [(set_attr "type" "A")])
2842 (define_insn "*cmpsi_adjusted"
2843 [(set (match_operand:CC 0 "register_operand" "=c")
2844 (match_operator:CC 1 "adjusted_comparison_operator"
2845 [(match_operand:SI 2 "gr_register_operand" "r")
2846 (match_operand:SI 3 "gr_reg_or_8bit_adjusted_operand" "rL")]))]
2848 "cmp4.%C1 %0, %I0 = %3, %2"
2849 [(set_attr "type" "A")])
2851 (define_insn "*cmpdi_normal"
2852 [(set (match_operand:CC 0 "register_operand" "=c")
2853 (match_operator:CC 1 "normal_comparison_operator"
2854 [(match_operand:DI 2 "gr_register_operand" "r")
2855 (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))]
2857 "cmp.%C1 %0, %I0 = %3, %2"
2858 [(set_attr "type" "A")])
2860 (define_insn "*cmpdi_adjusted"
2861 [(set (match_operand:CC 0 "register_operand" "=c")
2862 (match_operator:CC 1 "adjusted_comparison_operator"
2863 [(match_operand:DI 2 "gr_register_operand" "r")
2864 (match_operand:DI 3 "gr_reg_or_8bit_adjusted_operand" "rL")]))]
2866 "cmp.%C1 %0, %I0 = %3, %2"
2867 [(set_attr "type" "A")])
2869 (define_insn "*cmpsf_internal"
2870 [(set (match_operand:CC 0 "register_operand" "=c")
2871 (match_operator:CC 1 "comparison_operator"
2872 [(match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")
2873 (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")]))]
2875 "fcmp.%D1 %0, %I0 = %F2, %F3"
2876 [(set_attr "type" "F")])
2878 (define_insn "*cmpdf_internal"
2879 [(set (match_operand:CC 0 "register_operand" "=c")
2880 (match_operator:CC 1 "comparison_operator"
2881 [(match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")
2882 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")]))]
2884 "fcmp.%D1 %0, %I0 = %F2, %F3"
2885 [(set_attr "type" "F")])
2887 (define_insn "*cmptf_internal"
2888 [(set (match_operand:CC 0 "register_operand" "=c")
2889 (match_operator:CC 1 "comparison_operator"
2890 [(match_operand:TF 2 "tfreg_or_fp01_operand" "fG")
2891 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")]))]
2893 "fcmp.%D1 %0, %I0 = %F2, %F3"
2894 [(set_attr "type" "F")])
2896 ;; ??? Can this pattern be generated?
2898 (define_insn "*bit_zero"
2899 [(set (match_operand:CC 0 "register_operand" "=c")
2900 (eq:CC (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
2902 (match_operand:DI 2 "immediate_operand" "n"))
2905 "tbit.z %0, %I0 = %1, %2"
2906 [(set_attr "type" "I")])
2908 (define_insn "*bit_one"
2909 [(set (match_operand:CC 0 "register_operand" "=c")
2910 (ne:CC (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
2912 (match_operand:DI 2 "immediate_operand" "n"))
2915 "tbit.nz %0, %I0 = %1, %2"
2916 [(set_attr "type" "I")])
2918 ;; ??? We also need this if we run out of PR regs and need to spill some.
2920 ;; ??? We need this if a CCmode value does not get allocated to a hard
2921 ;; register. This happens if we cse/gcse a CCmode value across a call, and the
2922 ;; function has a nonlocal goto. This is because global does not allocate
2923 ;; call crossing pseudos to hard registers when current_function_has_
2924 ;; nonlocal_goto is true. This is relatively common for C++ programs that
2925 ;; use exceptions. See ia64_secondary_reload_class.
2927 ;; We use a define_expand here so that cse/gcse/combine can't accidentally
2928 ;; create movcc insns. If this was a named define_insn, we would not be able
2929 ;; to make it conditional on reload.
2931 (define_expand "movcc"
2932 [(set (match_operand:CC 0 "nonimmediate_operand" "")
2933 (match_operand:CC 1 "move_operand" ""))]
2937 if (! reload_in_progress && ! reload_completed)
2941 (define_insn "*movcc_internal"
2942 [(set (match_operand:CC 0 "nonimmediate_operand" "=r,c,r,m")
2943 (match_operand:CC 1 "move_operand" "c,r,m,r"))]
2944 "reload_in_progress || reload_completed"
2947 cmp4.ne %0, %I0 = %1, r0
2950 [(set_attr "type" "unknown,A,M,M")])
2953 [(set (match_operand:CC 0 "register_operand" "")
2954 (match_operand:CC 1 "register_operand" ""))]
2956 && GET_CODE (operands[0]) == REG && GR_REGNO_P (REGNO (operands[0]))
2957 && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
2959 (if_then_else:DI (ne:CC (match_dup 1) (const_int 0))
2963 (if_then_else:DI (ne:CC (match_dup 1) (const_int 0))
2966 "operands[2] = gen_rtx_SUBREG (DImode, operands[0], 0);")
2969 ;; ::::::::::::::::::::
2973 ;; ::::::::::::::::::::
2975 (define_expand "beq"
2977 (eq:CC (match_dup 2)
2980 (if_then_else (ne:CC (match_dup 1)
2982 (label_ref (match_operand 0 "" ""))
2987 operands[1] = gen_reg_rtx (CCmode);
2988 operands[2] = ia64_compare_op0;
2989 operands[3] = ia64_compare_op1;
2992 (define_expand "bne"
2994 (ne:CC (match_dup 2)
2997 (if_then_else (ne:CC (match_dup 1)
2999 (label_ref (match_operand 0 "" ""))
3004 operands[1] = gen_reg_rtx (CCmode);
3005 operands[2] = ia64_compare_op0;
3006 operands[3] = ia64_compare_op1;
3009 (define_expand "blt"
3011 (lt:CC (match_dup 2)
3014 (if_then_else (ne:CC (match_dup 1)
3016 (label_ref (match_operand 0 "" ""))
3021 operands[1] = gen_reg_rtx (CCmode);
3022 operands[2] = ia64_compare_op0;
3023 operands[3] = ia64_compare_op1;
3026 (define_expand "ble"
3028 (le:CC (match_dup 2)
3031 (if_then_else (ne:CC (match_dup 1)
3033 (label_ref (match_operand 0 "" ""))
3038 operands[1] = gen_reg_rtx (CCmode);
3039 operands[2] = ia64_compare_op0;
3040 operands[3] = ia64_compare_op1;
3043 (define_expand "bgt"
3045 (gt:CC (match_dup 2)
3048 (if_then_else (ne:CC (match_dup 1)
3050 (label_ref (match_operand 0 "" ""))
3055 operands[1] = gen_reg_rtx (CCmode);
3056 operands[2] = ia64_compare_op0;
3057 operands[3] = ia64_compare_op1;
3060 (define_expand "bge"
3062 (ge:CC (match_dup 2)
3065 (if_then_else (ne:CC (match_dup 1)
3067 (label_ref (match_operand 0 "" ""))
3072 operands[1] = gen_reg_rtx (CCmode);
3073 operands[2] = ia64_compare_op0;
3074 operands[3] = ia64_compare_op1;
3077 (define_expand "bltu"
3079 (ltu:CC (match_dup 2)
3082 (if_then_else (ne:CC (match_dup 1)
3084 (label_ref (match_operand 0 "" ""))
3089 operands[1] = gen_reg_rtx (CCmode);
3090 operands[2] = ia64_compare_op0;
3091 operands[3] = ia64_compare_op1;
3094 (define_expand "bleu"
3096 (leu:CC (match_dup 2)
3099 (if_then_else (ne:CC (match_dup 1)
3101 (label_ref (match_operand 0 "" ""))
3106 operands[1] = gen_reg_rtx (CCmode);
3107 operands[2] = ia64_compare_op0;
3108 operands[3] = ia64_compare_op1;
3111 (define_expand "bgtu"
3113 (gtu:CC (match_dup 2)
3116 (if_then_else (ne:CC (match_dup 1)
3118 (label_ref (match_operand 0 "" ""))
3123 operands[1] = gen_reg_rtx (CCmode);
3124 operands[2] = ia64_compare_op0;
3125 operands[3] = ia64_compare_op1;
3128 (define_expand "bgeu"
3130 (geu:CC (match_dup 2)
3133 (if_then_else (ne:CC (match_dup 1)
3135 (label_ref (match_operand 0 "" ""))
3140 operands[1] = gen_reg_rtx (CCmode);
3141 operands[2] = ia64_compare_op0;
3142 operands[3] = ia64_compare_op1;
3145 (define_expand "bunordered"
3147 (unordered:CC (match_dup 2)
3150 (if_then_else (ne:CC (match_dup 1)
3152 (label_ref (match_operand 0 "" ""))
3157 operands[1] = gen_reg_rtx (CCmode);
3158 operands[2] = ia64_compare_op0;
3159 operands[3] = ia64_compare_op1;
3162 (define_expand "bordered"
3164 (ordered:CC (match_dup 2)
3167 (if_then_else (ne:CC (match_dup 1)
3169 (label_ref (match_operand 0 "" ""))
3174 operands[1] = gen_reg_rtx (CCmode);
3175 operands[2] = ia64_compare_op0;
3176 operands[3] = ia64_compare_op1;
3179 (define_insn "*br_true"
3181 (if_then_else (match_operator 0 "predicate_operator"
3182 [(match_operand:CC 1 "register_operand" "c")
3184 (label_ref (match_operand 2 "" ""))
3187 "(%J0) br.cond%+ %l2"
3188 [(set_attr "type" "B")
3189 (set_attr "predicable" "no")])
3191 (define_insn "*br_false"
3193 (if_then_else (match_operator 0 "predicate_operator"
3194 [(match_operand:CC 1 "register_operand" "c")
3197 (label_ref (match_operand 2 "" ""))))]
3199 "(%j0) br.cond%+ %l2"
3200 [(set_attr "type" "B")
3201 (set_attr "predicable" "no")])
3203 ;; ::::::::::::::::::::
3205 ;; :: Counted loop operations
3207 ;; ::::::::::::::::::::
3209 (define_expand "doloop_end"
3210 [(use (match_operand 0 "" "")) ; loop pseudo
3211 (use (match_operand 1 "" "")) ; iterations; zero if unknown
3212 (use (match_operand 2 "" "")) ; max iterations
3213 (use (match_operand 3 "" "")) ; loop level
3214 (use (match_operand 4 "" ""))] ; label
3218 /* Only use cloop on innermost loops. */
3219 if (INTVAL (operands[3]) > 1)
3221 emit_jump_insn (gen_doloop_end_internal (gen_rtx_REG (DImode, AR_LC_REGNUM),
3226 (define_insn "doloop_end_internal"
3227 [(set (pc) (if_then_else (ne (match_operand:DI 0 "ar_lc_reg_operand" "")
3229 (label_ref (match_operand 1 "" ""))
3231 (set (match_dup 0) (if_then_else:DI (ne (match_dup 0) (const_int 0))
3233 (plus:DI (match_dup 0) (const_int -1))))]
3235 "br.cloop.sptk.few %l1"
3236 [(set_attr "type" "B")
3237 (set_attr "predicable" "no")])
3239 ;; ::::::::::::::::::::
3241 ;; :: Set flag operations
3243 ;; ::::::::::::::::::::
3245 (define_expand "seq"
3247 (eq:CC (match_dup 2)
3249 (set (match_operand:DI 0 "gr_register_operand" "")
3250 (ne:DI (match_dup 1) (const_int 0)))]
3254 operands[1] = gen_reg_rtx (CCmode);
3255 operands[2] = ia64_compare_op0;
3256 operands[3] = ia64_compare_op1;
3259 (define_expand "sne"
3261 (ne:CC (match_dup 2)
3263 (set (match_operand:DI 0 "gr_register_operand" "")
3264 (ne:DI (match_dup 1) (const_int 0)))]
3268 operands[1] = gen_reg_rtx (CCmode);
3269 operands[2] = ia64_compare_op0;
3270 operands[3] = ia64_compare_op1;
3273 (define_expand "slt"
3275 (lt:CC (match_dup 2)
3277 (set (match_operand:DI 0 "gr_register_operand" "")
3278 (ne:DI (match_dup 1) (const_int 0)))]
3282 operands[1] = gen_reg_rtx (CCmode);
3283 operands[2] = ia64_compare_op0;
3284 operands[3] = ia64_compare_op1;
3287 (define_expand "sle"
3289 (le:CC (match_dup 2)
3291 (set (match_operand:DI 0 "gr_register_operand" "")
3292 (ne:DI (match_dup 1) (const_int 0)))]
3296 operands[1] = gen_reg_rtx (CCmode);
3297 operands[2] = ia64_compare_op0;
3298 operands[3] = ia64_compare_op1;
3301 (define_expand "sgt"
3303 (gt:CC (match_dup 2)
3305 (set (match_operand:DI 0 "gr_register_operand" "")
3306 (ne:DI (match_dup 1) (const_int 0)))]
3310 operands[1] = gen_reg_rtx (CCmode);
3311 operands[2] = ia64_compare_op0;
3312 operands[3] = ia64_compare_op1;
3315 (define_expand "sge"
3317 (ge:CC (match_dup 2)
3319 (set (match_operand:DI 0 "gr_register_operand" "")
3320 (ne:DI (match_dup 1) (const_int 0)))]
3324 operands[1] = gen_reg_rtx (CCmode);
3325 operands[2] = ia64_compare_op0;
3326 operands[3] = ia64_compare_op1;
3329 (define_expand "sltu"
3331 (ltu:CC (match_dup 2)
3333 (set (match_operand:DI 0 "gr_register_operand" "")
3334 (ne:DI (match_dup 1) (const_int 0)))]
3338 operands[1] = gen_reg_rtx (CCmode);
3339 operands[2] = ia64_compare_op0;
3340 operands[3] = ia64_compare_op1;
3343 (define_expand "sleu"
3345 (leu:CC (match_dup 2)
3347 (set (match_operand:DI 0 "gr_register_operand" "")
3348 (ne:DI (match_dup 1) (const_int 0)))]
3352 operands[1] = gen_reg_rtx (CCmode);
3353 operands[2] = ia64_compare_op0;
3354 operands[3] = ia64_compare_op1;
3357 (define_expand "sgtu"
3359 (gtu:CC (match_dup 2)
3361 (set (match_operand:DI 0 "gr_register_operand" "")
3362 (ne:DI (match_dup 1) (const_int 0)))]
3366 operands[1] = gen_reg_rtx (CCmode);
3367 operands[2] = ia64_compare_op0;
3368 operands[3] = ia64_compare_op1;
3371 (define_expand "sgeu"
3373 (geu:CC (match_dup 2)
3375 (set (match_operand:DI 0 "gr_register_operand" "")
3376 (ne:DI (match_dup 1) (const_int 0)))]
3380 operands[1] = gen_reg_rtx (CCmode);
3381 operands[2] = ia64_compare_op0;
3382 operands[3] = ia64_compare_op1;
3385 (define_expand "sunordered"
3387 (unordered:CC (match_dup 2)
3389 (set (match_operand:DI 0 "gr_register_operand" "")
3390 (ne:DI (match_dup 1) (const_int 0)))]
3394 operands[1] = gen_reg_rtx (CCmode);
3395 operands[2] = ia64_compare_op0;
3396 operands[3] = ia64_compare_op1;
3399 (define_expand "sordered"
3401 (ordered:CC (match_dup 2)
3403 (set (match_operand:DI 0 "gr_register_operand" "")
3404 (ne:DI (match_dup 1) (const_int 0)))]
3408 operands[1] = gen_reg_rtx (CCmode);
3409 operands[2] = ia64_compare_op0;
3410 operands[3] = ia64_compare_op1;
3413 ;; Don't allow memory as destination here, because cmov/cmov/st is more
3414 ;; efficient than mov/mov/cst/cst.
3416 (define_insn_and_split "*sne_internal"
3417 [(set (match_operand:DI 0 "gr_register_operand" "=r")
3418 (ne:DI (match_operand:CC 1 "register_operand" "c")
3424 (if_then_else:DI (ne:CC (match_dup 1) (const_int 0))
3428 (if_then_else:DI (ne:CC (match_dup 1) (const_int 0))
3432 [(set_attr "type" "unknown")])
3434 ;; ??? Unknown if this can be matched.
3436 (define_insn_and_split "*seq_internal"
3437 [(set (match_operand:DI 0 "gr_register_operand" "=r")
3438 (eq:DI (match_operand:CC 1 "register_operand" "c")
3444 (if_then_else:DI (eq:CC (match_dup 1) (const_int 0))
3448 (if_then_else:DI (eq:CC (match_dup 1) (const_int 0))
3452 [(set_attr "type" "unknown")])
3455 ;; ::::::::::::::::::::
3457 ;; :: Conditional move instructions.
3459 ;; ::::::::::::::::::::
3461 ;; ??? Add movXXcc patterns?
3464 ;; DImode if_then_else patterns.
3467 ;; Errata 72 workaround.
3468 (define_insn "*cmovdi_internal_astep"
3469 [(set (match_operand:DI 0 "nonimmediate_operand"
3470 "=r,*f,Q,*b,r,*f,Q,*b,r,*f,Q,*b")
3472 (match_operator:CC 4 "predicate_operator"
3473 [(match_operand:CC 1 "register_operand"
3474 "c,c,c,c,c,c,c,c,c,c,c,c")
3476 (match_operand:DI 2 "general_operand"
3477 "0,0,0,0,ri*f*b,rO,*f,r,ri*f*b,rO,*f,r")
3478 (match_operand:DI 3 "general_operand"
3479 "ri*f*b,rO,*f,r,0,0,0,0,ri*f*b,rO,*f,r")))]
3482 [(set_attr "predicable" "no")])
3484 (define_insn "*cmovdi_internal"
3485 [(set (match_operand:DI 0 "nonimmediate_operand"
3486 "=r,m,*f,Q,*b,*d*e,r,m,*f,Q,*b,*d*e,r,m,*f,Q,*b,*d*e")
3488 (match_operator:CC 4 "predicate_operator"
3489 [(match_operand:CC 1 "register_operand"
3490 "c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c")
3492 (match_operand:DI 2 "general_operand"
3493 "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")
3494 (match_operand:DI 3 "general_operand"
3495 "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")))]
3498 [(set_attr "predicable" "no")])
3501 [(set (match_operand 0 "nonimmediate_operand" "")
3503 (match_operator:CC 4 "predicate_operator"
3504 [(match_operand:CC 1 "register_operand" "")
3506 (match_operand 2 "general_operand" "")
3507 (match_operand 3 "general_operand" "")))]
3513 if (! rtx_equal_p (operands[0], operands[2]))
3515 tmp = gen_rtx_SET (VOIDmode, operands[0], operands[2]);
3516 tmp = gen_rtx_COND_EXEC (VOIDmode, operands[4], tmp);
3519 if (! rtx_equal_p (operands[0], operands[3]))
3521 tmp = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
3522 CCmode, operands[1], const0_rtx);
3523 tmp = gen_rtx_COND_EXEC (VOIDmode, tmp,
3524 gen_rtx_SET (VOIDmode, operands[0],
3531 ;; Absolute value pattern.
3533 (define_insn "*absdi2_internal"
3534 [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
3536 (match_operator:CC 4 "predicate_operator"
3537 [(match_operand:CC 1 "register_operand" "c,c")
3539 (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" "rI,rI"))
3540 (match_operand:DI 3 "gr_reg_or_22bit_operand" "0,rI")))]
3543 [(set_attr "type" "A,unknown")
3544 (set_attr "predicable" "no")])
3547 [(set (match_operand:DI 0 "register_operand" "")
3549 (match_operator:CC 4 "predicate_operator"
3550 [(match_operand:CC 1 "register_operand" "c,c")
3552 (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" ""))
3553 (match_operand:DI 3 "gr_reg_or_22bit_operand" "")))]
3554 "reload_completed && rtx_equal_p (operands[0], operands[3])"
3558 (neg:DI (match_dup 2))))]
3562 [(set (match_operand:DI 0 "register_operand" "")
3564 (match_operator:CC 4 "predicate_operator"
3565 [(match_operand:CC 1 "register_operand" "c,c")
3567 (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" ""))
3568 (match_operand:DI 3 "gr_reg_or_22bit_operand" "")))]
3572 (set (match_dup 0) (neg:DI (match_dup 2))))
3575 (set (match_dup 0) (match_dup 3)))]
3578 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
3579 CCmode, operands[1], const0_rtx);
3583 ;; SImode if_then_else patterns.
3586 (define_insn "*cmovsi_internal_astep"
3587 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,*f,r,*f,r,*f")
3589 (match_operator:CC 4 "predicate_operator"
3590 [(match_operand:CC 1 "register_operand" "c,c,c,c,c,c")
3592 (match_operand:SI 2 "general_operand"
3593 "0,0,ri*f,rO,ri*f,rO")
3594 (match_operand:SI 3 "general_operand"
3595 "ri*f,rO,0,0,ri*f,rO")))]
3598 [(set_attr "predicable" "no")])
3600 (define_insn "*cmovsi_internal"
3601 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,*f,r,m,*f,r,m,*f")
3603 (match_operator:CC 4 "predicate_operator"
3604 [(match_operand:CC 1 "register_operand" "c,c,c,c,c,c,c,c,c")
3606 (match_operand:SI 2 "general_operand"
3607 "0,0,0,rim*f,rO,rO,rim*f,rO,rO")
3608 (match_operand:SI 3 "general_operand"
3609 "rim*f,rO,rO,0,0,0,rim*f,rO,rO")))]
3612 [(set_attr "predicable" "no")])
3614 (define_insn "*abssi2_internal"
3615 [(set (match_operand:SI 0 "gr_register_operand" "=r,r")
3617 (match_operator:CC 4 "predicate_operator"
3618 [(match_operand:CC 1 "register_operand" "c,c")
3620 (neg:SI (match_operand:SI 3 "gr_reg_or_22bit_operand" "rI,rI"))
3621 (match_operand:SI 2 "gr_reg_or_22bit_operand" "0,rI")))]
3624 [(set_attr "type" "A,unknown")
3625 (set_attr "predicable" "no")])
3628 [(set (match_operand:SI 0 "register_operand" "")
3630 (match_operator:CC 4 "predicate_operator"
3631 [(match_operand:CC 1 "register_operand" "c,c")
3633 (neg:SI (match_operand:SI 2 "gr_reg_or_22bit_operand" ""))
3634 (match_operand:SI 3 "gr_reg_or_22bit_operand" "")))]
3635 "reload_completed && rtx_equal_p (operands[0], operands[3])"
3639 (neg:SI (match_dup 2))))]
3643 [(set (match_operand:SI 0 "register_operand" "")
3645 (match_operator:CC 4 "predicate_operator"
3646 [(match_operand:CC 1 "register_operand" "c,c")
3648 (neg:SI (match_operand:SI 2 "gr_reg_or_22bit_operand" ""))
3649 (match_operand:SI 3 "gr_reg_or_22bit_operand" "")))]
3653 (set (match_dup 0) (neg:SI (match_dup 2))))
3656 (set (match_dup 0) (match_dup 3)))]
3659 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
3660 CCmode, operands[1], const0_rtx);
3664 ;; ::::::::::::::::::::
3666 ;; :: Call and branch instructions
3668 ;; ::::::::::::::::::::
3670 ;; Subroutine call instruction returning no value. Operand 0 is the function
3671 ;; to call; operand 1 is the number of bytes of arguments pushed (in mode
3672 ;; `SImode', except it is normally a `const_int'); operand 2 is the number of
3673 ;; registers used as operands.
3675 ;; On most machines, operand 2 is not actually stored into the RTL pattern. It
3676 ;; is supplied for the sake of some RISC machines which need to put this
3677 ;; information into the assembler code; they can put it in the RTL instead of
3680 (define_expand "call"
3681 [(use (match_operand:DI 0 "" ""))
3682 (use (match_operand 1 "" ""))
3683 (use (match_operand 2 "" ""))
3684 (use (match_operand 3 "" ""))]
3688 /* ??? Stripping off the MEM isn't correct. Will lose alias info. */
3689 rtx addr = XEXP (operands[0], 0);
3690 enum machine_mode mode = GET_MODE (addr);
3692 if (TARGET_NO_PIC || TARGET_AUTO_PIC)
3693 emit_call_insn (gen_call_internal (addr, operands[1],
3694 gen_rtx_REG (DImode, R_BR (0))));
3696 /* If this is an indirect call, then we have the address of a descriptor. */
3697 else if (! symbolic_operand (addr, mode))
3698 emit_insn (gen_indirect_call_pic (addr, operands[1]));
3699 else if (TARGET_CONST_GP)
3700 emit_call_insn (gen_call_internal (addr, operands[1],
3701 gen_rtx_REG (DImode, R_BR (0))));
3703 emit_insn (gen_call_pic (addr, operands[1]));
3708 (define_expand "indirect_call_pic"
3709 [(set (match_dup 2) (reg:DI 1))
3710 (set (match_dup 3) (mem:DI (match_operand 0 "" "")))
3711 (set (match_dup 4) (plus:DI (match_dup 0) (const_int 8)))
3712 (set (reg:DI 1) (mem:DI (match_dup 4)))
3713 (parallel [(call (mem:DI (match_dup 3)) (match_operand 1 "" ""))
3715 (clobber (reg:DI 320))])
3716 (set (reg:DI 1) (match_dup 2))]
3720 operands[2] = ia64_gp_save_reg (0);
3721 operands[3] = gen_reg_rtx (DImode);
3722 operands[4] = gen_reg_rtx (DImode);
3725 ;; ??? Saving/restoring the GP register is not needed if we are calling
3726 ;; a function in the same module.
3728 (define_expand "call_pic"
3729 [(set (match_dup 2) (reg:DI 1))
3730 (parallel [(call (mem:DI (match_operand 0 "" "")) (match_operand 1 "" ""))
3732 (clobber (reg:DI 320))])
3733 (set (reg:DI 1) (match_dup 2))]
3737 /* ??? Using setjmp_operand is an unsatisfying solution. Should rethink. */
3738 operands[2] = ia64_gp_save_reg (setjmp_operand (XEXP (operands[0], 0),
3742 (define_insn "call_internal"
3743 [(call (mem:DI (match_operand:DI 0 "call_operand" "bi"))
3744 (match_operand 1 "" ""))
3745 (clobber (match_operand:DI 2 "register_operand" "=b"))]
3747 "br.call%+.many %2 = %0"
3748 [(set_attr "type" "B")])
3750 (define_insn "*call_internal1"
3751 [(call (mem:DI (match_operand:DI 0 "call_operand" "bi"))
3752 (match_operand 1 "" ""))
3754 (clobber (match_operand:DI 2 "register_operand" "=b"))]
3756 "br.call%+.many %2 = %0"
3757 [(set_attr "type" "B")])
3759 ;; Subroutine call instruction returning a value. Operand 0 is the hard
3760 ;; register in which the value is returned. There are three more operands, the
3761 ;; same as the three operands of the `call' instruction (but with numbers
3762 ;; increased by one).
3764 ;; Subroutines that return `BLKmode' objects use the `call' insn.
3766 (define_expand "call_value"
3767 [(use (match_operand 0 "" ""))
3768 (use (match_operand:DI 1 "" ""))
3769 (use (match_operand 2 "" ""))
3770 (use (match_operand 3 "" ""))
3771 (use (match_operand 4 "" ""))]
3775 /* ??? Stripping off the MEM isn't correct. Will lose alias info. */
3776 rtx addr = XEXP (operands[1], 0);
3777 enum machine_mode mode = GET_MODE (addr);
3779 if (TARGET_NO_PIC || TARGET_AUTO_PIC)
3780 emit_call_insn (gen_call_value_internal (operands[0], addr, operands[2],
3781 gen_rtx_REG (DImode, R_BR (0))));
3783 /* If this is an indirect call, then we have the address of a descriptor. */
3784 else if (! symbolic_operand (addr, mode))
3786 /* This is for HFA returns. */
3787 if (GET_CODE (operands[0]) == PARALLEL)
3788 emit_insn (gen_indirect_call_multiple_values_pic (operands[0], addr,
3791 emit_insn (gen_indirect_call_value_pic (operands[0], addr,
3794 else if (TARGET_CONST_GP)
3795 emit_call_insn (gen_call_value_internal (operands[0], addr, operands[2],
3796 gen_rtx_REG (DImode, R_BR (0))));
3797 /* This is for HFA returns. */
3798 else if (GET_CODE (operands[0]) == PARALLEL)
3799 emit_insn (gen_call_multiple_values_pic (operands[0], addr, operands[2]));
3801 emit_insn (gen_call_value_pic (operands[0], addr, operands[2]));
3806 (define_expand "indirect_call_value_pic"
3807 [(set (match_dup 3) (reg:DI 1))
3808 (set (match_dup 4) (mem:DI (match_operand 1 "" "")))
3809 (set (match_dup 5) (plus:DI (match_dup 1) (const_int 8)))
3810 (set (reg:DI 1) (mem:DI (match_dup 5)))
3811 (parallel [(set (match_operand 0 "" "")
3812 (call (mem:DI (match_dup 4)) (match_operand 2 "" "")))
3814 (clobber (reg:DI 320))])
3815 (set (reg:DI 1) (match_dup 3))]
3819 operands[3] = ia64_gp_save_reg (0);
3820 operands[4] = gen_reg_rtx (DImode);
3821 operands[5] = gen_reg_rtx (DImode);
3824 (define_expand "indirect_call_multiple_values_pic"
3825 [(set (match_dup 3) (reg:DI 1))
3826 (set (match_dup 4) (mem:DI (match_operand 1 "" "")))
3827 (set (match_dup 5) (plus:DI (match_dup 1) (const_int 8)))
3828 (set (reg:DI 1) (mem:DI (match_dup 5)))
3829 (match_par_dup 6 [(set (match_operand 0 "" "")
3830 (call (mem:DI (match_dup 4))
3831 (match_operand 2 "" "")))
3833 (clobber (reg:DI 320))])
3834 (set (reg:DI 1) (match_dup 3))]
3842 operands[3] = ia64_gp_save_reg (0);
3843 operands[4] = gen_reg_rtx (DImode);
3844 operands[5] = gen_reg_rtx (DImode);
3846 /* This code is the same as the code in call_multiple_values_pic, except
3847 that op3 was replaced with op6 and op1 was replaced with op4. */
3848 call = gen_rtx_CALL (VOIDmode, gen_rtx_MEM (DImode, operands[4]),
3851 count = XVECLEN (operands[0], 0);
3852 operands[6] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 2));
3854 XVECEXP (operands[6], 0, 0)
3855 = gen_rtx_SET (VOIDmode, XEXP (XVECEXP (operands[0], 0, 0), 0), call);
3857 XVECEXP (operands[6], 0, 1)
3858 = gen_rtx_USE (DImode, gen_rtx_REG (DImode, GR_REG (1)));
3859 XVECEXP (operands[6], 0, 2)
3860 = gen_rtx_CLOBBER (DImode, gen_rtx_REG (DImode, BR_REG (0)));
3862 for (i = 1; i < count; i++)
3863 XVECEXP (operands[6], 0, i + 2)
3864 = gen_rtx_SET (VOIDmode, XEXP (XVECEXP (operands[0], 0, i), 0), call);
3868 ;; ??? Saving/restoring the GP register is not needed if we are calling
3869 ;; a function in the same module.
3871 (define_expand "call_value_pic"
3872 [(set (match_dup 3) (reg:DI 1))
3873 (parallel [(set (match_operand 0 "" "")
3874 (call (mem:DI (match_operand 1 "" ""))
3875 (match_operand 2 "" "")))
3877 (clobber (reg:DI 320))])
3878 (set (reg:DI 1) (match_dup 3))]
3882 /* ??? Using setjmp_operand is an unsatisfying solution. Should rethink. */
3883 operands[3] = ia64_gp_save_reg (setjmp_operand (XEXP (operands[1], 0),
3887 ;; ??? Saving/restoring the GP register is not needed if we are calling
3888 ;; a function in the same module.
3890 (define_expand "call_multiple_values_pic"
3891 [(set (match_dup 4) (reg:DI 1))
3892 (match_par_dup 3 [(set (match_operand 0 "" "")
3893 (call (mem:DI (match_operand 1 "" ""))
3894 (match_operand 2 "" "")))
3896 (clobber (reg:DI 320))])
3897 (set (reg:DI 1) (match_dup 4))]
3905 operands[4] = ia64_gp_save_reg (0);
3907 call = gen_rtx_CALL (VOIDmode, gen_rtx_MEM (DImode, operands[1]),
3910 count = XVECLEN (operands[0], 0);
3911 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 2));
3913 XVECEXP (operands[3], 0, 0)
3914 = gen_rtx_SET (VOIDmode, XEXP (XVECEXP (operands[0], 0, 0), 0), call);
3916 XVECEXP (operands[3], 0, 1)
3917 = gen_rtx_USE (DImode, gen_rtx_REG (DImode, GR_REG (1)));
3918 XVECEXP (operands[3], 0, 2)
3919 = gen_rtx_CLOBBER (DImode, gen_rtx_REG (DImode, BR_REG (0)));
3921 for (i = 1; i < count; i++)
3922 XVECEXP (operands[3], 0, i + 2)
3923 = gen_rtx_SET (VOIDmode, XEXP (XVECEXP (operands[0], 0, i), 0), call);
3926 (define_insn "call_value_internal"
3927 [(set (match_operand 0 "register_operand" "=rf")
3928 (call (mem:DI (match_operand:DI 1 "call_operand" "bi"))
3929 (match_operand 2 "" "")))
3930 (clobber (match_operand:DI 3 "register_operand" "=b"))]
3932 "br.call%+.many %3 = %1"
3933 [(set_attr "type" "B")])
3935 (define_insn "*call_value_internal1"
3936 [(set (match_operand 0 "register_operand" "=rf")
3937 (call (mem:DI (match_operand:DI 1 "call_operand" "bi"))
3938 (match_operand 2 "" "")))
3940 (clobber (match_operand:DI 3 "register_operand" "=b"))]
3942 "br.call%+.many %3 = %1"
3943 [(set_attr "type" "B")])
3945 (define_insn "*call_multiple_values_internal1"
3946 [(match_parallel 0 "call_multiple_values_operation"
3947 [(set (match_operand 1 "register_operand" "=rf")
3948 (call (mem:DI (match_operand:DI 2 "call_operand" "bi"))
3949 (match_operand 3 "" "")))
3951 (clobber (match_operand:DI 4 "register_operand" "=b"))])]
3953 "br.call%+.many %4 = %2"
3954 [(set_attr "type" "B")])
3956 ;; Call subroutine returning any type.
3958 (define_expand "untyped_call"
3959 [(parallel [(call (match_operand 0 "" "")
3961 (match_operand 1 "" "")
3962 (match_operand 2 "" "")])]
3968 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
3970 for (i = 0; i < XVECLEN (operands[2], 0); i++)
3972 rtx set = XVECEXP (operands[2], 0, i);
3973 emit_move_insn (SET_DEST (set), SET_SRC (set));
3976 /* The optimizer does not know that the call sets the function value
3977 registers we stored in the result block. We avoid problems by
3978 claiming that all hard registers are used and clobbered at this
3980 emit_insn (gen_blockage ());
3985 (define_insn "return_internal"
3987 (use (match_operand:DI 0 "register_operand" "b"))]
3989 "br.ret.sptk.many %0"
3990 [(set_attr "type" "B")])
3992 (define_insn "return"
3994 "ia64_direct_return ()"
3995 "br.ret.sptk.many rp"
3996 [(set_attr "type" "B")])
3998 (define_insn "*return_true"
4000 (if_then_else (match_operator 0 "predicate_operator"
4001 [(match_operand:CC 1 "register_operand" "c")
4005 "ia64_direct_return ()"
4006 "(%J0) br.ret%+.many rp"
4007 [(set_attr "type" "B")
4008 (set_attr "predicable" "no")])
4010 (define_insn "*return_false"
4012 (if_then_else (match_operator 0 "predicate_operator"
4013 [(match_operand:CC 1 "register_operand" "c")
4017 "ia64_direct_return ()"
4018 "(%j0) br.ret%+.many rp"
4019 [(set_attr "type" "B")
4020 (set_attr "predicable" "no")])
4023 [(set (pc) (label_ref (match_operand 0 "" "")))]
4026 [(set_attr "type" "B")])
4028 (define_insn "indirect_jump"
4029 [(set (pc) (match_operand:DI 0 "register_operand" "b"))]
4032 [(set_attr "type" "B")])
4034 (define_expand "tablejump"
4035 [(match_operand:DI 0 "register_operand" "")
4036 (match_operand 1 "" "")]
4040 rtx tmp1 = gen_reg_rtx (DImode);
4041 rtx tmp2 = gen_reg_rtx (DImode);
4043 emit_move_insn (tmp1, gen_rtx_LABEL_REF (Pmode, operands[1]));
4044 emit_insn (gen_adddi3 (tmp2, operands[0], tmp1));
4045 emit_jump_insn (gen_tablejump_internal (tmp2, operands[1]));
4049 (define_insn "tablejump_internal"
4050 [(set (pc) (match_operand:DI 0 "register_operand" "b"))
4051 (use (label_ref (match_operand 1 "" "")))]
4054 [(set_attr "type" "B")])
4057 ;; ::::::::::::::::::::
4059 ;; :: Prologue and Epilogue instructions
4061 ;; ::::::::::::::::::::
4063 (define_expand "prologue"
4068 ia64_expand_prologue ();
4072 (define_expand "epilogue"
4077 ia64_expand_epilogue ();
4081 ;; This prevents the scheduler from moving the SP decrement past FP-relative
4082 ;; stack accesses. This is the same as adddi3 plus the extra set.
4084 (define_insn "prologue_allocate_stack"
4085 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4086 (plus:DI (match_operand:DI 1 "register_operand" "%r,r,a")
4087 (match_operand:DI 2 "gr_reg_or_22bit_operand" "r,I,J")))
4088 (set (match_operand:DI 3 "register_operand" "=r,r,r")
4095 [(set_attr "type" "A")])
4097 ;; This prevents the scheduler from moving the SP restore past FP-relative
4098 ;; stack accesses. This is similar to movdi plus the extra set.
4100 (define_insn "epilogue_deallocate_stack"
4101 [(set (match_operand:DI 0 "register_operand" "=r")
4102 (match_operand:DI 1 "register_operand" "+r"))
4103 (set (match_dup 1) (match_dup 1))]
4106 [(set_attr "type" "A")])
4108 ;; Allocate a new register frame.
4110 (define_insn "alloc"
4111 [(set (match_operand:DI 0 "register_operand" "=r")
4112 (unspec_volatile:DI [(const_int 0)] 0))
4113 (use (match_operand:DI 1 "const_int_operand" "i"))
4114 (use (match_operand:DI 2 "const_int_operand" "i"))
4115 (use (match_operand:DI 3 "const_int_operand" "i"))
4116 (use (match_operand:DI 4 "const_int_operand" "i"))]
4118 "alloc %0 = ar.pfs, %1, %2, %3, %4"
4119 [(set_attr "type" "M")
4120 (set_attr "predicable" "no")])
4123 (define_expand "gr_spill"
4124 [(parallel [(set (match_operand:DI 0 "memory_operand" "=m")
4125 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
4126 (match_operand:DI 2 "const_int_operand" "")] 1))
4127 (clobber (match_dup 3))])]
4129 "operands[3] = gen_rtx_REG (DImode, AR_UNAT_REGNUM);")
4131 (define_insn "gr_spill_internal"
4132 [(set (match_operand:DI 0 "memory_operand" "=m")
4133 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
4134 (match_operand:DI 2 "const_int_operand" "")] 1))
4135 (clobber (match_operand:DI 3 "register_operand" ""))]
4137 ".mem.offset %2, 0\;st8.spill %0 = %1%P0"
4138 [(set_attr "type" "M")])
4141 (define_expand "gr_restore"
4142 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
4143 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
4144 (match_operand:DI 2 "const_int_operand" "")] 2))
4145 (use (match_dup 3))])]
4147 "operands[3] = gen_rtx_REG (DImode, AR_UNAT_REGNUM);")
4149 (define_insn "gr_restore_internal"
4150 [(set (match_operand:DI 0 "register_operand" "=r")
4151 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
4152 (match_operand:DI 2 "const_int_operand" "")] 2))
4153 (use (match_operand:DI 3 "register_operand" ""))]
4155 ".mem.offset %2, 0\;ld8.fill %0 = %1%P1"
4156 [(set_attr "type" "M")])
4158 (define_insn "fr_spill"
4159 [(set (match_operand:TF 0 "memory_operand" "=m")
4160 (unspec:TF [(match_operand:TF 1 "register_operand" "f")] 3))]
4162 "stf.spill %0 = %1%P0"
4163 [(set_attr "type" "M")])
4165 (define_insn "fr_restore"
4166 [(set (match_operand:TF 0 "register_operand" "=f")
4167 (unspec:TF [(match_operand:TF 1 "memory_operand" "m")] 4))]
4169 "ldf.fill %0 = %1%P1"
4170 [(set_attr "type" "M")])
4172 (define_insn "bsp_value"
4173 [(set (match_operand:DI 0 "register_operand" "=r")
4174 (unspec:DI [(const_int 0)] 20))]
4177 [(set_attr "type" "I")])
4179 (define_insn "set_bsp"
4180 [(unspec_volatile [(const_int 0)] 5)
4181 (use (match_operand:DI 0 "register_operand" "r"))]
4183 "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"
4184 [(set_attr "type" "unknown")
4185 (set_attr "predicable" "no")])
4187 (define_insn "flushrs"
4188 [(unspec [(const_int 0)] 21)]
4191 [(set_attr "type" "M")])
4193 ;; ::::::::::::::::::::
4195 ;; :: Miscellaneous instructions
4197 ;; ::::::::::::::::::::
4199 ;; ??? Emiting a NOP instruction isn't very useful. This should probably
4200 ;; be emitting ";;" to force a break in the instruction packing.
4202 ;; No operation, needed in case the user uses -g but not -O.
4207 [(set_attr "type" "unknown")])
4209 ;; Pseudo instruction that prevents the scheduler from moving code above this
4211 (define_insn "blockage"
4212 [(unspec_volatile [(const_int 0)] 1)]
4215 [(set_attr "type" "unknown")
4216 (set_attr "predicable" "no")])
4218 (define_insn "insn_group_barrier"
4219 [(unspec_volatile [(const_int 0)] 2)]
4222 [(set_attr "type" "S")
4223 (set_attr "predicable" "no")])
4226 ;; Non-local goto support.
4228 (define_expand "save_stack_nonlocal"
4229 [(use (match_operand:OI 0 "memory_operand" ""))
4230 (use (match_operand:DI 1 "register_operand" ""))]
4234 emit_library_call (gen_rtx_SYMBOL_REF (Pmode,
4235 \"__ia64_save_stack_nonlocal\"),
4236 0, VOIDmode, 2, XEXP (operands[0], 0), Pmode,
4237 operands[1], Pmode);
4241 (define_expand "nonlocal_goto"
4242 [(use (match_operand 0 "general_operand" ""))
4243 (use (match_operand 1 "general_operand" ""))
4244 (use (match_operand 2 "general_operand" ""))
4245 (use (match_operand 3 "general_operand" ""))]
4249 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, \"__ia64_nonlocal_goto\"),
4252 copy_to_reg (XEXP (operands[2], 0)), Pmode,
4253 operands[3], Pmode);
4258 ;; Restore the GP after the exception/longjmp. The preceeding call will
4259 ;; have tucked it away.
4260 (define_expand "exception_receiver"
4261 [(set (reg:DI 1) (match_dup 0))]
4263 "operands[0] = ia64_gp_save_reg (0);")
4265 ;; The rest of the setjmp processing happens with the nonlocal_goto expander.
4266 ;; ??? This is not tested.
4267 (define_expand "builtin_setjmp_setup"
4268 [(use (match_operand:DI 0 "" ""))]
4272 emit_move_insn (ia64_gp_save_reg (0), gen_rtx_REG (DImode, GR_REG (1)));
4276 (define_expand "builtin_setjmp_receiver"
4277 [(use (match_operand:DI 0 "" ""))]
4281 emit_move_insn (gen_rtx_REG (DImode, GR_REG (1)), ia64_gp_save_reg (0));
4285 (define_expand "eh_epilogue"
4286 [(use (match_operand:DI 0 "register_operand" "r"))
4287 (use (match_operand:DI 1 "register_operand" "r"))
4288 (use (match_operand:DI 2 "register_operand" "r"))]
4292 rtx bsp = gen_rtx_REG (Pmode, 10);
4293 rtx sp = gen_rtx_REG (Pmode, 9);
4295 if (GET_CODE (operands[0]) != REG || REGNO (operands[0]) != 10)
4297 emit_move_insn (bsp, operands[0]);
4300 if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 9)
4302 emit_move_insn (sp, operands[2]);
4305 emit_insn (gen_rtx_USE (VOIDmode, sp));
4306 emit_insn (gen_rtx_USE (VOIDmode, bsp));
4308 cfun->machine->ia64_eh_epilogue_sp = sp;
4309 cfun->machine->ia64_eh_epilogue_bsp = bsp;
4312 ;; Builtin apply support.
4314 (define_expand "restore_stack_nonlocal"
4315 [(use (match_operand:DI 0 "register_operand" ""))
4316 (use (match_operand:OI 1 "memory_operand" ""))]
4320 emit_library_call (gen_rtx_SYMBOL_REF (Pmode,
4321 \"__ia64_restore_stack_nonlocal\"),
4323 copy_to_reg (XEXP (operands[1], 0)), Pmode);
4328 ;;; Intrinsics support.
4331 [(set (mem:BLK (match_dup 0))
4332 (unspec:BLK [(mem:BLK (match_dup 0))] 12))]
4336 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (DImode));
4337 MEM_VOLATILE_P (operands[0]) = 1;
4340 (define_insn "*mf_internal"
4341 [(set (match_operand:BLK 0 "" "")
4342 (unspec:BLK [(match_operand:BLK 1 "" "")] 12))]
4345 [(set_attr "type" "M")])
4347 (define_insn "fetchadd_acq_si"
4348 [(set (match_operand:SI 0 "gr_register_operand" "=r")
4350 (set (match_operand:SI 1 "not_postinc_memory_operand" "+S")
4351 (unspec:SI [(match_dup 1)
4352 (match_operand:SI 2 "fetchadd_operand" "n")] 19))]
4354 "fetchadd4.acq %0 = %1, %2"
4355 [(set_attr "type" "M")])
4357 (define_insn "fetchadd_acq_di"
4358 [(set (match_operand:DI 0 "gr_register_operand" "=r")
4360 (set (match_operand:DI 1 "not_postinc_memory_operand" "+S")
4361 (unspec:DI [(match_dup 1)
4362 (match_operand:DI 2 "fetchadd_operand" "n")] 19))]
4364 "fetchadd8.acq %0 = %1, %2"
4365 [(set_attr "type" "M")])
4367 (define_insn "cmpxchg_acq_si"
4368 [(set (match_operand:SI 0 "gr_register_operand" "=r")
4370 (set (match_operand:SI 1 "not_postinc_memory_operand" "+S")
4371 (unspec:SI [(match_dup 1)
4372 (match_operand:SI 2 "gr_register_operand" "r")
4373 (match_operand:SI 3 "ar_ccv_reg_operand" "")] 13))]
4375 "cmpxchg4.acq %0 = %1, %2, %3"
4376 [(set_attr "type" "M")])
4378 (define_insn "cmpxchg_acq_di"
4379 [(set (match_operand:DI 0 "gr_register_operand" "=r")
4381 (set (match_operand:DI 1 "not_postinc_memory_operand" "+S")
4382 (unspec:DI [(match_dup 1)
4383 (match_operand:DI 2 "gr_register_operand" "r")
4384 (match_operand:DI 3 "ar_ccv_reg_operand" "")] 13))]
4386 "cmpxchg8.acq %0 = %1, %2, %3"
4387 [(set_attr "type" "M")])
4389 (define_insn "xchgsi"
4390 [(set (match_operand:SI 0 "gr_register_operand" "=r")
4391 (match_operand:SI 1 "not_postinc_memory_operand" "+S"))
4393 (match_operand:SI 2 "gr_register_operand" "r"))]
4396 [(set_attr "type" "M")])
4398 (define_insn "xchgdi"
4399 [(set (match_operand:DI 0 "gr_register_operand" "=r")
4400 (match_operand:DI 1 "not_postinc_memory_operand" "+S"))
4402 (match_operand:DI 2 "gr_register_operand" "r"))]
4405 [(set_attr "type" "M")])
4410 [(match_operator 0 "predicate_operator"
4411 [(match_operand:CC 1 "register_operand" "c")
4416 (define_insn "pred_rel_mutex"
4417 [(unspec_volatile [(match_operand:CC 0 "register_operand" "c")] 7)]
4419 ".pred.rel.mutex %0, %I0"
4420 [(set_attr "type" "unknown")
4421 (set_attr "predicable" "no")])
4423 (define_insn "safe_across_calls_all"
4424 [(unspec_volatile [(const_int 0)] 8)]
4426 ".pred.safe_across_calls p1-p63"
4427 [(set_attr "type" "unknown")
4428 (set_attr "predicable" "no")])
4430 (define_insn "safe_across_calls_normal"
4431 [(unspec_volatile [(const_int 0)] 9)]
4435 emit_safe_across_calls (asm_out_file);
4438 [(set_attr "type" "unknown")
4439 (set_attr "predicable" "no")])