1 ;; Machine description for SPARC chip for GCC
2 ;; Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;; 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
4 ;; 2011 Free Software Foundation, Inc.
5 ;; Contributed by Michael Tiemann (tiemann@cygnus.com)
6 ;; 64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
9 ;; This file is part of GCC.
11 ;; GCC is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 3, or (at your option)
16 ;; GCC is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ;; GNU General Public License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GCC; see the file COPYING3. If not see
23 ;; <http://www.gnu.org/licenses/>.
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 (UNSPEC_UPDATE_RETURN 1)
30 (UNSPEC_LOAD_PCREL_SYM 2)
31 (UNSPEC_MOVE_PIC_LABEL 5)
37 (UNSPEC_EMB_TEXTUHI 13)
38 (UNSPEC_EMB_TEXTHI 14)
39 (UNSPEC_EMB_TEXTULO 15)
41 (UNSPEC_MOVE_GOTDATA 19)
50 (UNSPEC_TLSLD_BASE 35)
83 (UNSPECV_PROBE_STACK_RANGE 11)
176 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
177 (define_mode_iterator I [QI HI SI DI])
178 (define_mode_iterator F [SF DF TF])
180 ;; We don't define V1SI because SI should work just fine.
181 (define_mode_iterator V32 [SF V2HI V4QI])
182 (define_mode_iterator V32I [SI V2HI V4QI])
184 (define_mode_iterator V64 [DF V2SI V4HI V8QI])
185 (define_mode_iterator V64I [DI V2SI V4HI V8QI])
187 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
188 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
189 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
190 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
191 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
194 ;; Attribute for cpu type.
195 ;; These must match the values for enum processor_type in sparc.h.
216 (const (symbol_ref "sparc_cpu_attr")))
218 ;; Attribute for the instruction set.
219 ;; At present we only need to distinguish v9/!v9, but for clarity we
220 ;; test TARGET_V8 too.
221 (define_attr "isa" "v7,v8,v9,sparclet"
223 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
224 (symbol_ref "TARGET_V8") (const_string "v8")
225 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
226 (const_string "v7"))))
232 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
240 fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,edge,gsr,
243 multi,savew,flushw,iflush,trap"
244 (const_string "ialu"))
246 ;; True if branch/call has empty delay slot and will emit a nop in it
247 (define_attr "empty_delay_slot" "false,true"
248 (symbol_ref "(empty_delay_slot (insn)
249 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
251 (define_attr "branch_type" "none,icc,fcc,reg"
252 (const_string "none"))
254 (define_attr "pic" "false,true"
255 (symbol_ref "(flag_pic != 0 ? PIC_TRUE : PIC_FALSE)"))
257 (define_attr "calls_alloca" "false,true"
258 (symbol_ref "(cfun->calls_alloca != 0
259 ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)"))
261 (define_attr "calls_eh_return" "false,true"
262 (symbol_ref "(crtl->calls_eh_return != 0
263 ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)"))
265 (define_attr "leaf_function" "false,true"
266 (symbol_ref "(current_function_uses_only_leaf_regs != 0
267 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
269 (define_attr "delayed_branch" "false,true"
270 (symbol_ref "(flag_delayed_branch != 0
271 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
273 (define_attr "flat" "false,true"
274 (symbol_ref "(TARGET_FLAT != 0
275 ? FLAT_TRUE : FLAT_FALSE)"))
277 ;; Length (in # of insns).
278 ;; Beware that setting a length greater or equal to 3 for conditional branches
279 ;; has a side-effect (see output_cbranch and output_v9branch).
280 (define_attr "length" ""
281 (cond [(eq_attr "type" "uncond_branch,call")
282 (if_then_else (eq_attr "empty_delay_slot" "true")
285 (eq_attr "type" "sibcall")
286 (if_then_else (eq_attr "leaf_function" "true")
287 (if_then_else (eq_attr "empty_delay_slot" "true")
290 (if_then_else (eq_attr "empty_delay_slot" "true")
293 (eq_attr "branch_type" "icc")
294 (if_then_else (match_operand 0 "noov_compare64_operator" "")
295 (if_then_else (lt (pc) (match_dup 1))
296 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
297 (if_then_else (eq_attr "empty_delay_slot" "true")
300 (if_then_else (eq_attr "empty_delay_slot" "true")
303 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
304 (if_then_else (eq_attr "empty_delay_slot" "true")
307 (if_then_else (eq_attr "empty_delay_slot" "true")
310 (if_then_else (eq_attr "empty_delay_slot" "true")
313 (eq_attr "branch_type" "fcc")
314 (if_then_else (match_operand 0 "fcc0_register_operand" "")
315 (if_then_else (eq_attr "empty_delay_slot" "true")
316 (if_then_else (not (match_test "TARGET_V9"))
319 (if_then_else (not (match_test "TARGET_V9"))
322 (if_then_else (lt (pc) (match_dup 2))
323 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
324 (if_then_else (eq_attr "empty_delay_slot" "true")
327 (if_then_else (eq_attr "empty_delay_slot" "true")
330 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
331 (if_then_else (eq_attr "empty_delay_slot" "true")
334 (if_then_else (eq_attr "empty_delay_slot" "true")
337 (eq_attr "branch_type" "reg")
338 (if_then_else (lt (pc) (match_dup 2))
339 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
340 (if_then_else (eq_attr "empty_delay_slot" "true")
343 (if_then_else (eq_attr "empty_delay_slot" "true")
346 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
347 (if_then_else (eq_attr "empty_delay_slot" "true")
350 (if_then_else (eq_attr "empty_delay_slot" "true")
356 (define_attr "fptype" "single,double"
357 (const_string "single"))
359 ;; UltraSPARC-III integer load type.
360 (define_attr "us3load_type" "2cycle,3cycle"
361 (const_string "2cycle"))
363 (define_asm_attributes
364 [(set_attr "length" "2")
365 (set_attr "type" "multi")])
367 ;; Attributes for instruction and branch scheduling
368 (define_attr "tls_call_delay" "false,true"
369 (symbol_ref "(tls_call_delay (insn)
370 ? TLS_CALL_DELAY_TRUE : TLS_CALL_DELAY_FALSE)"))
372 (define_attr "in_call_delay" "false,true"
373 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
374 (const_string "false")
375 (eq_attr "type" "load,fpload,store,fpstore")
376 (if_then_else (eq_attr "length" "1")
377 (const_string "true")
378 (const_string "false"))]
379 (if_then_else (and (eq_attr "length" "1")
380 (eq_attr "tls_call_delay" "true"))
381 (const_string "true")
382 (const_string "false"))))
384 (define_attr "eligible_for_sibcall_delay" "false,true"
385 (symbol_ref "(eligible_for_sibcall_delay (insn)
386 ? ELIGIBLE_FOR_SIBCALL_DELAY_TRUE
387 : ELIGIBLE_FOR_SIBCALL_DELAY_FALSE)"))
389 (define_attr "eligible_for_return_delay" "false,true"
390 (symbol_ref "(eligible_for_return_delay (insn)
391 ? ELIGIBLE_FOR_RETURN_DELAY_TRUE
392 : ELIGIBLE_FOR_RETURN_DELAY_FALSE)"))
394 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
395 ;; branches. This would allow us to remove the nop always inserted before
396 ;; a floating point branch.
398 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
399 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
400 ;; This is because doing so will add several pipeline stalls to the path
401 ;; that the load/store did not come from. Unfortunately, there is no way
402 ;; to prevent fill_eager_delay_slots from using load/store without completely
403 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
404 ;; because it prevents us from moving back the final store of inner loops.
406 (define_attr "in_branch_delay" "false,true"
407 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
408 (eq_attr "length" "1"))
409 (const_string "true")
410 (const_string "false")))
412 (define_attr "in_uncond_branch_delay" "false,true"
413 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
414 (eq_attr "length" "1"))
415 (const_string "true")
416 (const_string "false")))
418 (define_attr "in_annul_branch_delay" "false,true"
419 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
420 (eq_attr "length" "1"))
421 (const_string "true")
422 (const_string "false")))
424 (define_delay (eq_attr "type" "call")
425 [(eq_attr "in_call_delay" "true") (nil) (nil)])
427 (define_delay (eq_attr "type" "sibcall")
428 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
430 (define_delay (eq_attr "type" "branch")
431 [(eq_attr "in_branch_delay" "true")
432 (nil) (eq_attr "in_annul_branch_delay" "true")])
434 (define_delay (eq_attr "type" "uncond_branch")
435 [(eq_attr "in_uncond_branch_delay" "true")
438 (define_delay (eq_attr "type" "return")
439 [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
442 ;; Include SPARC DFA schedulers
444 (include "cypress.md")
445 (include "supersparc.md")
446 (include "hypersparc.md")
448 (include "sparclet.md")
449 (include "ultra1_2.md")
450 (include "ultra3.md")
451 (include "niagara.md")
452 (include "niagara2.md")
455 ;; Operand and operator predicates and constraints
457 (include "predicates.md")
458 (include "constraints.md")
461 ;; Compare instructions.
463 ;; These are just the DEFINE_INSNs to match the patterns and the
464 ;; DEFINE_SPLITs for some of the scc insns that actually require
465 ;; more than one machine instruction. DEFINE_EXPANDs are further down.
467 ;; The compare DEFINE_INSNs.
469 (define_insn "*cmpsi_insn"
470 [(set (reg:CC CC_REG)
471 (compare:CC (match_operand:SI 0 "register_operand" "r")
472 (match_operand:SI 1 "arith_operand" "rI")))]
475 [(set_attr "type" "compare")])
477 (define_insn "*cmpdi_sp64"
478 [(set (reg:CCX CC_REG)
479 (compare:CCX (match_operand:DI 0 "register_operand" "r")
480 (match_operand:DI 1 "arith_operand" "rI")))]
483 [(set_attr "type" "compare")])
485 (define_insn "*cmpsf_fpe"
486 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
487 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
488 (match_operand:SF 2 "register_operand" "f")))]
492 return "fcmpes\t%0, %1, %2";
493 return "fcmpes\t%1, %2";
495 [(set_attr "type" "fpcmp")])
497 (define_insn "*cmpdf_fpe"
498 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
499 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
500 (match_operand:DF 2 "register_operand" "e")))]
504 return "fcmped\t%0, %1, %2";
505 return "fcmped\t%1, %2";
507 [(set_attr "type" "fpcmp")
508 (set_attr "fptype" "double")])
510 (define_insn "*cmptf_fpe"
511 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
512 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
513 (match_operand:TF 2 "register_operand" "e")))]
514 "TARGET_FPU && TARGET_HARD_QUAD"
517 return "fcmpeq\t%0, %1, %2";
518 return "fcmpeq\t%1, %2";
520 [(set_attr "type" "fpcmp")])
522 (define_insn "*cmpsf_fp"
523 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
524 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
525 (match_operand:SF 2 "register_operand" "f")))]
529 return "fcmps\t%0, %1, %2";
530 return "fcmps\t%1, %2";
532 [(set_attr "type" "fpcmp")])
534 (define_insn "*cmpdf_fp"
535 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
536 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
537 (match_operand:DF 2 "register_operand" "e")))]
541 return "fcmpd\t%0, %1, %2";
542 return "fcmpd\t%1, %2";
544 [(set_attr "type" "fpcmp")
545 (set_attr "fptype" "double")])
547 (define_insn "*cmptf_fp"
548 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
549 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
550 (match_operand:TF 2 "register_operand" "e")))]
551 "TARGET_FPU && TARGET_HARD_QUAD"
554 return "fcmpq\t%0, %1, %2";
555 return "fcmpq\t%1, %2";
557 [(set_attr "type" "fpcmp")])
559 ;; Next come the scc insns.
561 (define_expand "cstoresi4"
562 [(use (match_operator 1 "comparison_operator"
563 [(match_operand:SI 2 "compare_operand" "")
564 (match_operand:SI 3 "arith_operand" "")]))
565 (clobber (match_operand:SI 0 "register_operand"))]
568 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
569 operands[2] = force_reg (SImode, operands[2]);
570 if (emit_scc_insn (operands)) DONE; else FAIL;
573 (define_expand "cstoredi4"
574 [(use (match_operator 1 "comparison_operator"
575 [(match_operand:DI 2 "compare_operand" "")
576 (match_operand:DI 3 "arith_operand" "")]))
577 (clobber (match_operand:SI 0 "register_operand"))]
580 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
581 operands[2] = force_reg (DImode, operands[2]);
582 if (emit_scc_insn (operands)) DONE; else FAIL;
585 (define_expand "cstore<F:mode>4"
586 [(use (match_operator 1 "comparison_operator"
587 [(match_operand:F 2 "register_operand" "")
588 (match_operand:F 3 "register_operand" "")]))
589 (clobber (match_operand:SI 0 "register_operand"))]
591 { if (emit_scc_insn (operands)) DONE; else FAIL; })
595 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
596 ;; generate addcc/subcc instructions.
598 (define_expand "seqsi_special"
600 (xor:SI (match_operand:SI 1 "register_operand" "")
601 (match_operand:SI 2 "register_operand" "")))
602 (parallel [(set (match_operand:SI 0 "register_operand" "")
603 (eq:SI (match_dup 3) (const_int 0)))
604 (clobber (reg:CC CC_REG))])]
606 { operands[3] = gen_reg_rtx (SImode); })
608 (define_expand "seqdi_special"
610 (xor:DI (match_operand:DI 1 "register_operand" "")
611 (match_operand:DI 2 "register_operand" "")))
612 (set (match_operand:SI 0 "register_operand" "")
613 (eq:SI (match_dup 3) (const_int 0)))]
615 { operands[3] = gen_reg_rtx (DImode); })
617 (define_expand "snesi_special"
619 (xor:SI (match_operand:SI 1 "register_operand" "")
620 (match_operand:SI 2 "register_operand" "")))
621 (parallel [(set (match_operand:SI 0 "register_operand" "")
622 (ne:SI (match_dup 3) (const_int 0)))
623 (clobber (reg:CC CC_REG))])]
625 { operands[3] = gen_reg_rtx (SImode); })
627 (define_expand "snedi_special"
629 (xor:DI (match_operand:DI 1 "register_operand" "")
630 (match_operand:DI 2 "register_operand" "")))
631 (set (match_operand:SI 0 "register_operand" "")
632 (ne:SI (match_dup 3) (const_int 0)))]
634 { operands[3] = gen_reg_rtx (DImode); })
637 ;; Now the DEFINE_INSNs for the scc cases.
639 ;; The SEQ and SNE patterns are special because they can be done
640 ;; without any branching and do not involve a COMPARE. We want
641 ;; them to always use the splits below so the results can be
644 (define_insn_and_split "*snesi_zero"
645 [(set (match_operand:SI 0 "register_operand" "=r")
646 (ne:SI (match_operand:SI 1 "register_operand" "r")
648 (clobber (reg:CC CC_REG))]
652 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
654 (set (match_dup 0) (ltu:SI (reg:CC CC_REG) (const_int 0)))]
656 [(set_attr "length" "2")])
658 (define_insn_and_split "*neg_snesi_zero"
659 [(set (match_operand:SI 0 "register_operand" "=r")
660 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
662 (clobber (reg:CC CC_REG))]
666 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
668 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
670 [(set_attr "length" "2")])
672 (define_insn_and_split "*snesi_zero_extend"
673 [(set (match_operand:DI 0 "register_operand" "=r")
674 (ne:DI (match_operand:SI 1 "register_operand" "r")
676 (clobber (reg:CC CC_REG))]
680 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0)
683 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
685 (ltu:SI (reg:CC_NOOV CC_REG)
688 [(set_attr "length" "2")])
690 (define_insn_and_split "*snedi_zero"
691 [(set (match_operand:DI 0 "register_operand" "=&r")
692 (ne:DI (match_operand:DI 1 "register_operand" "r")
696 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
697 [(set (match_dup 0) (const_int 0))
698 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
703 [(set_attr "length" "2")])
705 (define_insn_and_split "*neg_snedi_zero"
706 [(set (match_operand:DI 0 "register_operand" "=&r")
707 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
711 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
712 [(set (match_dup 0) (const_int 0))
713 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
718 [(set_attr "length" "2")])
720 (define_insn_and_split "*snedi_zero_trunc"
721 [(set (match_operand:SI 0 "register_operand" "=&r")
722 (ne:SI (match_operand:DI 1 "register_operand" "r")
726 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
727 [(set (match_dup 0) (const_int 0))
728 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
733 [(set_attr "length" "2")])
735 (define_insn_and_split "*seqsi_zero"
736 [(set (match_operand:SI 0 "register_operand" "=r")
737 (eq:SI (match_operand:SI 1 "register_operand" "r")
739 (clobber (reg:CC CC_REG))]
743 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
745 (set (match_dup 0) (geu:SI (reg:CC CC_REG) (const_int 0)))]
747 [(set_attr "length" "2")])
749 (define_insn_and_split "*neg_seqsi_zero"
750 [(set (match_operand:SI 0 "register_operand" "=r")
751 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
753 (clobber (reg:CC CC_REG))]
757 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
759 (set (match_dup 0) (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
761 [(set_attr "length" "2")])
763 (define_insn_and_split "*seqsi_zero_extend"
764 [(set (match_operand:DI 0 "register_operand" "=r")
765 (eq:DI (match_operand:SI 1 "register_operand" "r")
767 (clobber (reg:CC CC_REG))]
771 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0)
774 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
776 (ltu:SI (reg:CC_NOOV CC_REG)
779 [(set_attr "length" "2")])
781 (define_insn_and_split "*seqdi_zero"
782 [(set (match_operand:DI 0 "register_operand" "=&r")
783 (eq:DI (match_operand:DI 1 "register_operand" "r")
787 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
788 [(set (match_dup 0) (const_int 0))
789 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
794 [(set_attr "length" "2")])
796 (define_insn_and_split "*neg_seqdi_zero"
797 [(set (match_operand:DI 0 "register_operand" "=&r")
798 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
802 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
803 [(set (match_dup 0) (const_int 0))
804 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
809 [(set_attr "length" "2")])
811 (define_insn_and_split "*seqdi_zero_trunc"
812 [(set (match_operand:SI 0 "register_operand" "=&r")
813 (eq:SI (match_operand:DI 1 "register_operand" "r")
817 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
818 [(set (match_dup 0) (const_int 0))
819 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
824 [(set_attr "length" "2")])
826 ;; We can also do (x + (i == 0)) and related, so put them in.
827 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
830 (define_insn_and_split "*x_plus_i_ne_0"
831 [(set (match_operand:SI 0 "register_operand" "=r")
832 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
834 (match_operand:SI 2 "register_operand" "r")))
835 (clobber (reg:CC CC_REG))]
839 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
841 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
844 [(set_attr "length" "2")])
846 (define_insn_and_split "*x_minus_i_ne_0"
847 [(set (match_operand:SI 0 "register_operand" "=r")
848 (minus:SI (match_operand:SI 2 "register_operand" "r")
849 (ne:SI (match_operand:SI 1 "register_operand" "r")
851 (clobber (reg:CC CC_REG))]
855 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
857 (set (match_dup 0) (minus:SI (match_dup 2)
858 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
860 [(set_attr "length" "2")])
862 (define_insn_and_split "*x_plus_i_eq_0"
863 [(set (match_operand:SI 0 "register_operand" "=r")
864 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
866 (match_operand:SI 2 "register_operand" "r")))
867 (clobber (reg:CC CC_REG))]
871 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
873 (set (match_dup 0) (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
876 [(set_attr "length" "2")])
878 (define_insn_and_split "*x_minus_i_eq_0"
879 [(set (match_operand:SI 0 "register_operand" "=r")
880 (minus:SI (match_operand:SI 2 "register_operand" "r")
881 (eq:SI (match_operand:SI 1 "register_operand" "r")
883 (clobber (reg:CC CC_REG))]
887 [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
889 (set (match_dup 0) (minus:SI (match_dup 2)
890 (geu:SI (reg:CC CC_REG) (const_int 0))))]
892 [(set_attr "length" "2")])
894 ;; We can also do GEU and LTU directly, but these operate after a compare.
895 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
898 (define_insn "*sltu_insn"
899 [(set (match_operand:SI 0 "register_operand" "=r")
900 (ltu:SI (reg:CC CC_REG) (const_int 0)))]
903 [(set_attr "type" "ialuX")])
905 (define_insn "*neg_sltu_insn"
906 [(set (match_operand:SI 0 "register_operand" "=r")
907 (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
910 [(set_attr "type" "ialuX")])
912 ;; ??? Combine should canonicalize these next two to the same pattern.
913 (define_insn "*neg_sltu_minus_x"
914 [(set (match_operand:SI 0 "register_operand" "=r")
915 (minus:SI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))
916 (match_operand:SI 1 "arith_operand" "rI")))]
919 [(set_attr "type" "ialuX")])
921 (define_insn "*neg_sltu_plus_x"
922 [(set (match_operand:SI 0 "register_operand" "=r")
923 (neg:SI (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
924 (match_operand:SI 1 "arith_operand" "rI"))))]
927 [(set_attr "type" "ialuX")])
929 (define_insn "*sgeu_insn"
930 [(set (match_operand:SI 0 "register_operand" "=r")
931 (geu:SI (reg:CC CC_REG) (const_int 0)))]
934 [(set_attr "type" "ialuX")])
936 (define_insn "*neg_sgeu_insn"
937 [(set (match_operand:SI 0 "register_operand" "=r")
938 (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
941 [(set_attr "type" "ialuX")])
943 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
944 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
947 (define_insn "*sltu_plus_x"
948 [(set (match_operand:SI 0 "register_operand" "=r")
949 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
950 (match_operand:SI 1 "arith_operand" "rI")))]
953 [(set_attr "type" "ialuX")])
955 (define_insn "*sltu_plus_x_plus_y"
956 [(set (match_operand:SI 0 "register_operand" "=r")
957 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
958 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
959 (match_operand:SI 2 "arith_operand" "rI"))))]
962 [(set_attr "type" "ialuX")])
964 (define_insn "*x_minus_sltu"
965 [(set (match_operand:SI 0 "register_operand" "=r")
966 (minus:SI (match_operand:SI 1 "register_operand" "r")
967 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
970 [(set_attr "type" "ialuX")])
972 ;; ??? Combine should canonicalize these next two to the same pattern.
973 (define_insn "*x_minus_y_minus_sltu"
974 [(set (match_operand:SI 0 "register_operand" "=r")
975 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
976 (match_operand:SI 2 "arith_operand" "rI"))
977 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
980 [(set_attr "type" "ialuX")])
982 (define_insn "*x_minus_sltu_plus_y"
983 [(set (match_operand:SI 0 "register_operand" "=r")
984 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
985 (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
986 (match_operand:SI 2 "arith_operand" "rI"))))]
989 [(set_attr "type" "ialuX")])
991 (define_insn "*sgeu_plus_x"
992 [(set (match_operand:SI 0 "register_operand" "=r")
993 (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
994 (match_operand:SI 1 "register_operand" "r")))]
997 [(set_attr "type" "ialuX")])
999 (define_insn "*x_minus_sgeu"
1000 [(set (match_operand:SI 0 "register_operand" "=r")
1001 (minus:SI (match_operand:SI 1 "register_operand" "r")
1002 (geu:SI (reg:CC CC_REG) (const_int 0))))]
1005 [(set_attr "type" "ialuX")])
1008 [(set (match_operand:SI 0 "register_operand" "")
1009 (match_operator:SI 2 "noov_compare_operator"
1010 [(match_operand 1 "icc_or_fcc_register_operand" "")
1013 && REGNO (operands[1]) == SPARC_ICC_REG
1014 && (GET_MODE (operands[1]) == CCXmode
1015 /* 32-bit LTU/GEU are better implemented using addx/subx. */
1016 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1017 [(set (match_dup 0) (const_int 0))
1019 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1025 ;; These control RTL generation for conditional jump insns
1027 (define_expand "cbranchcc4"
1029 (if_then_else (match_operator 0 "comparison_operator"
1030 [(match_operand 1 "compare_operand" "")
1031 (match_operand 2 "const_zero_operand" "")])
1032 (label_ref (match_operand 3 "" ""))
1037 (define_expand "cbranchsi4"
1038 [(use (match_operator 0 "comparison_operator"
1039 [(match_operand:SI 1 "compare_operand" "")
1040 (match_operand:SI 2 "arith_operand" "")]))
1041 (use (match_operand 3 ""))]
1044 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1045 operands[1] = force_reg (SImode, operands[1]);
1046 emit_conditional_branch_insn (operands);
1050 (define_expand "cbranchdi4"
1051 [(use (match_operator 0 "comparison_operator"
1052 [(match_operand:DI 1 "compare_operand" "")
1053 (match_operand:DI 2 "arith_operand" "")]))
1054 (use (match_operand 3 ""))]
1057 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1058 operands[1] = force_reg (DImode, operands[1]);
1059 emit_conditional_branch_insn (operands);
1063 (define_expand "cbranch<F:mode>4"
1064 [(use (match_operator 0 "comparison_operator"
1065 [(match_operand:F 1 "register_operand" "")
1066 (match_operand:F 2 "register_operand" "")]))
1067 (use (match_operand 3 ""))]
1069 { emit_conditional_branch_insn (operands); DONE; })
1072 ;; Now match both normal and inverted jump.
1074 ;; XXX fpcmp nop braindamage
1075 (define_insn "*normal_branch"
1077 (if_then_else (match_operator 0 "noov_compare_operator"
1078 [(reg CC_REG) (const_int 0)])
1079 (label_ref (match_operand 1 "" ""))
1083 return output_cbranch (operands[0], operands[1], 1, 0,
1084 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1087 [(set_attr "type" "branch")
1088 (set_attr "branch_type" "icc")])
1090 ;; XXX fpcmp nop braindamage
1091 (define_insn "*inverted_branch"
1093 (if_then_else (match_operator 0 "noov_compare_operator"
1094 [(reg CC_REG) (const_int 0)])
1096 (label_ref (match_operand 1 "" ""))))]
1099 return output_cbranch (operands[0], operands[1], 1, 1,
1100 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1103 [(set_attr "type" "branch")
1104 (set_attr "branch_type" "icc")])
1106 ;; XXX fpcmp nop braindamage
1107 (define_insn "*normal_fp_branch"
1109 (if_then_else (match_operator 1 "comparison_operator"
1110 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1112 (label_ref (match_operand 2 "" ""))
1116 return output_cbranch (operands[1], operands[2], 2, 0,
1117 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1120 [(set_attr "type" "branch")
1121 (set_attr "branch_type" "fcc")])
1123 ;; XXX fpcmp nop braindamage
1124 (define_insn "*inverted_fp_branch"
1126 (if_then_else (match_operator 1 "comparison_operator"
1127 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1130 (label_ref (match_operand 2 "" ""))))]
1133 return output_cbranch (operands[1], operands[2], 2, 1,
1134 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1137 [(set_attr "type" "branch")
1138 (set_attr "branch_type" "fcc")])
1140 ;; XXX fpcmp nop braindamage
1141 (define_insn "*normal_fpe_branch"
1143 (if_then_else (match_operator 1 "comparison_operator"
1144 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1146 (label_ref (match_operand 2 "" ""))
1150 return output_cbranch (operands[1], operands[2], 2, 0,
1151 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1154 [(set_attr "type" "branch")
1155 (set_attr "branch_type" "fcc")])
1157 ;; XXX fpcmp nop braindamage
1158 (define_insn "*inverted_fpe_branch"
1160 (if_then_else (match_operator 1 "comparison_operator"
1161 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1164 (label_ref (match_operand 2 "" ""))))]
1167 return output_cbranch (operands[1], operands[2], 2, 1,
1168 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1171 [(set_attr "type" "branch")
1172 (set_attr "branch_type" "fcc")])
1174 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1175 ;; in the architecture.
1177 ;; There are no 32 bit brreg insns.
1180 (define_insn "*normal_int_branch_sp64"
1182 (if_then_else (match_operator 0 "v9_register_compare_operator"
1183 [(match_operand:DI 1 "register_operand" "r")
1185 (label_ref (match_operand 2 "" ""))
1189 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1190 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1193 [(set_attr "type" "branch")
1194 (set_attr "branch_type" "reg")])
1197 (define_insn "*inverted_int_branch_sp64"
1199 (if_then_else (match_operator 0 "v9_register_compare_operator"
1200 [(match_operand:DI 1 "register_operand" "r")
1203 (label_ref (match_operand 2 "" ""))))]
1206 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1207 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1210 [(set_attr "type" "branch")
1211 (set_attr "branch_type" "reg")])
1214 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1215 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1216 ;; that adds the PC value at the call point to register #(operand 3).
1218 (define_insn "load_pcrel_sym<P:mode>"
1219 [(set (match_operand:P 0 "register_operand" "=r")
1220 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1221 (match_operand:P 2 "call_address_operand" "")
1222 (match_operand:P 3 "const_int_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1223 (clobber (reg:P O7_REG))]
1224 "REGNO (operands[0]) == INTVAL (operands[3])"
1226 if (flag_delayed_branch)
1227 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1229 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1231 [(set (attr "type") (const_string "multi"))
1232 (set (attr "length")
1233 (if_then_else (eq_attr "delayed_branch" "true")
1238 ;; Integer move instructions
1240 (define_expand "movqi"
1241 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1242 (match_operand:QI 1 "general_operand" ""))]
1245 if (sparc_expand_move (QImode, operands))
1249 (define_insn "*movqi_insn"
1250 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1251 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1252 "(register_operand (operands[0], QImode)
1253 || register_or_zero_operand (operands[1], QImode))"
1258 [(set_attr "type" "*,load,store")
1259 (set_attr "us3load_type" "*,3cycle,*")])
1261 (define_expand "movhi"
1262 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1263 (match_operand:HI 1 "general_operand" ""))]
1266 if (sparc_expand_move (HImode, operands))
1270 (define_insn "*movhi_insn"
1271 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1272 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1273 "(register_operand (operands[0], HImode)
1274 || register_or_zero_operand (operands[1], HImode))"
1277 sethi\t%%hi(%a1), %0
1280 [(set_attr "type" "*,*,load,store")
1281 (set_attr "us3load_type" "*,*,3cycle,*")])
1283 ;; We always work with constants here.
1284 (define_insn "*movhi_lo_sum"
1285 [(set (match_operand:HI 0 "register_operand" "=r")
1286 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1287 (match_operand:HI 2 "small_int_operand" "I")))]
1291 (define_expand "movsi"
1292 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1293 (match_operand:SI 1 "general_operand" ""))]
1296 if (sparc_expand_move (SImode, operands))
1300 (define_insn "*movsi_insn"
1301 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d,d")
1302 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,f,m,f,J,P"))]
1303 "(register_operand (operands[0], SImode)
1304 || register_or_zero_or_all_ones_operand (operands[1], SImode))"
1307 sethi\t%%hi(%a1), %0
1315 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga,fga")])
1317 (define_insn "*movsi_lo_sum"
1318 [(set (match_operand:SI 0 "register_operand" "=r")
1319 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1320 (match_operand:SI 2 "immediate_operand" "in")))]
1322 "or\t%1, %%lo(%a2), %0")
1324 (define_insn "*movsi_high"
1325 [(set (match_operand:SI 0 "register_operand" "=r")
1326 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1328 "sethi\t%%hi(%a1), %0")
1330 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1331 ;; so that CSE won't optimize the address computation away.
1332 (define_insn "movsi_lo_sum_pic"
1333 [(set (match_operand:SI 0 "register_operand" "=r")
1334 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1335 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1338 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1339 return "xor\t%1, %%gdop_lox10(%a2), %0";
1341 return "or\t%1, %%lo(%a2), %0";
1345 (define_insn "movsi_high_pic"
1346 [(set (match_operand:SI 0 "register_operand" "=r")
1347 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1348 "flag_pic && check_pic (1)"
1350 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1351 return "sethi\t%%gdop_hix22(%a1), %0";
1353 return "sethi\t%%hi(%a1), %0";
1357 (define_insn "movsi_pic_gotdata_op"
1358 [(set (match_operand:SI 0 "register_operand" "=r")
1359 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1360 (match_operand:SI 2 "register_operand" "r")
1361 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1362 "flag_pic && check_pic (1)"
1364 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1365 return "ld\t[%1 + %2], %0, %%gdop(%a3)";
1367 return "ld\t[%1 + %2], %0";
1370 [(set_attr "type" "load")])
1372 (define_expand "movsi_pic_label_ref"
1373 [(set (match_dup 3) (high:SI
1374 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1375 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1376 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1377 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1378 (set (match_operand:SI 0 "register_operand" "=r")
1379 (minus:SI (match_dup 5) (match_dup 4)))]
1382 crtl->uses_pic_offset_table = 1;
1383 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1384 if (!can_create_pseudo_p ())
1386 operands[3] = operands[0];
1387 operands[4] = operands[0];
1391 operands[3] = gen_reg_rtx (SImode);
1392 operands[4] = gen_reg_rtx (SImode);
1394 operands[5] = pic_offset_table_rtx;
1397 (define_insn "*movsi_high_pic_label_ref"
1398 [(set (match_operand:SI 0 "register_operand" "=r")
1400 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1401 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1403 "sethi\t%%hi(%a2-(%a1-.)), %0")
1405 (define_insn "*movsi_lo_sum_pic_label_ref"
1406 [(set (match_operand:SI 0 "register_operand" "=r")
1407 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1408 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1409 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1411 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1413 ;; Set up the PIC register for VxWorks.
1415 (define_expand "vxworks_load_got"
1417 (high:SI (match_dup 1)))
1419 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1421 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1422 "TARGET_VXWORKS_RTP"
1424 operands[0] = pic_offset_table_rtx;
1425 operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1426 operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1429 (define_expand "movdi"
1430 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1431 (match_operand:DI 1 "general_operand" ""))]
1434 if (sparc_expand_move (DImode, operands))
1438 ;; Be careful, fmovd does not exist when !v9.
1439 ;; We match MEM moves directly when we have correct even
1440 ;; numbered registers, but fall into splits otherwise.
1441 ;; The constraint ordering here is really important to
1442 ;; avoid insane problems in reload, especially for patterns
1445 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1446 ;; (const_int -5016)))
1450 (define_insn "*movdi_insn_sp32"
1451 [(set (match_operand:DI 0 "nonimmediate_operand"
1452 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1453 (match_operand:DI 1 "input_operand"
1454 " J,U,T,r,o,i,r, f, T, o, f, f"))]
1456 && (register_operand (operands[0], DImode)
1457 || register_or_zero_operand (operands[1], DImode))"
1471 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1472 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1474 (define_insn "*movdi_insn_sp32_v9"
1475 [(set (match_operand:DI 0 "nonimmediate_operand"
1476 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1477 (match_operand:DI 1 "input_operand"
1478 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1481 && (register_operand (operands[0], DImode)
1482 || register_or_zero_operand (operands[1], DImode))"
1499 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
1500 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
1501 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
1503 (define_insn "*movdi_insn_sp64"
1504 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b,b")
1505 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,e,W,e,J,P"))]
1507 && (register_operand (operands[0], DImode)
1508 || register_or_zero_or_all_ones_operand (operands[1], DImode))"
1511 sethi\t%%hi(%a1), %0
1519 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga,fga")
1520 (set_attr "fptype" "*,*,*,*,double,*,*,double,double")])
1522 (define_expand "movdi_pic_label_ref"
1523 [(set (match_dup 3) (high:DI
1524 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1525 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1526 (set (match_dup 4) (lo_sum:DI (match_dup 3)
1527 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1528 (set (match_operand:DI 0 "register_operand" "=r")
1529 (minus:DI (match_dup 5) (match_dup 4)))]
1530 "TARGET_ARCH64 && flag_pic"
1532 crtl->uses_pic_offset_table = 1;
1533 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1534 if (!can_create_pseudo_p ())
1536 operands[3] = operands[0];
1537 operands[4] = operands[0];
1541 operands[3] = gen_reg_rtx (DImode);
1542 operands[4] = gen_reg_rtx (DImode);
1544 operands[5] = pic_offset_table_rtx;
1547 (define_insn "*movdi_high_pic_label_ref"
1548 [(set (match_operand:DI 0 "register_operand" "=r")
1550 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1551 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1552 "TARGET_ARCH64 && flag_pic"
1553 "sethi\t%%hi(%a2-(%a1-.)), %0")
1555 (define_insn "*movdi_lo_sum_pic_label_ref"
1556 [(set (match_operand:DI 0 "register_operand" "=r")
1557 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1558 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
1559 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1560 "TARGET_ARCH64 && flag_pic"
1561 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1563 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
1564 ;; in sparc.c to see what is going on here... PIC stuff comes first.
1566 (define_insn "movdi_lo_sum_pic"
1567 [(set (match_operand:DI 0 "register_operand" "=r")
1568 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1569 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1570 "TARGET_ARCH64 && flag_pic"
1572 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1573 return "xor\t%1, %%gdop_lox10(%a2), %0";
1575 return "or\t%1, %%lo(%a2), %0";
1579 (define_insn "movdi_high_pic"
1580 [(set (match_operand:DI 0 "register_operand" "=r")
1581 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1582 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1584 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1585 return "sethi\t%%gdop_hix22(%a1), %0";
1587 return "sethi\t%%hi(%a1), %0";
1591 (define_insn "movdi_pic_gotdata_op"
1592 [(set (match_operand:DI 0 "register_operand" "=r")
1593 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1594 (match_operand:DI 2 "register_operand" "r")
1595 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1596 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1598 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1599 return "ldx\t[%1 + %2], %0, %%gdop(%a3)";
1601 return "ldx\t[%1 + %2], %0";
1604 [(set_attr "type" "load")])
1606 (define_insn "*sethi_di_medlow_embmedany_pic"
1607 [(set (match_operand:DI 0 "register_operand" "=r")
1608 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
1609 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
1610 "sethi\t%%hi(%a1), %0")
1612 (define_insn "*sethi_di_medlow"
1613 [(set (match_operand:DI 0 "register_operand" "=r")
1614 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
1615 "TARGET_CM_MEDLOW && check_pic (1)"
1616 "sethi\t%%hi(%a1), %0")
1618 (define_insn "*losum_di_medlow"
1619 [(set (match_operand:DI 0 "register_operand" "=r")
1620 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1621 (match_operand:DI 2 "symbolic_operand" "")))]
1623 "or\t%1, %%lo(%a2), %0")
1625 (define_insn "seth44"
1626 [(set (match_operand:DI 0 "register_operand" "=r")
1627 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
1629 "sethi\t%%h44(%a1), %0")
1631 (define_insn "setm44"
1632 [(set (match_operand:DI 0 "register_operand" "=r")
1633 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1634 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
1636 "or\t%1, %%m44(%a2), %0")
1638 (define_insn "setl44"
1639 [(set (match_operand:DI 0 "register_operand" "=r")
1640 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1641 (match_operand:DI 2 "symbolic_operand" "")))]
1643 "or\t%1, %%l44(%a2), %0")
1645 (define_insn "sethh"
1646 [(set (match_operand:DI 0 "register_operand" "=r")
1647 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
1649 "sethi\t%%hh(%a1), %0")
1651 (define_insn "setlm"
1652 [(set (match_operand:DI 0 "register_operand" "=r")
1653 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
1655 "sethi\t%%lm(%a1), %0")
1657 (define_insn "sethm"
1658 [(set (match_operand:DI 0 "register_operand" "=r")
1659 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1660 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
1662 "or\t%1, %%hm(%a2), %0")
1664 (define_insn "setlo"
1665 [(set (match_operand:DI 0 "register_operand" "=r")
1666 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1667 (match_operand:DI 2 "symbolic_operand" "")))]
1669 "or\t%1, %%lo(%a2), %0")
1671 (define_insn "embmedany_sethi"
1672 [(set (match_operand:DI 0 "register_operand" "=r")
1673 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
1674 "TARGET_CM_EMBMEDANY && check_pic (1)"
1675 "sethi\t%%hi(%a1), %0")
1677 (define_insn "embmedany_losum"
1678 [(set (match_operand:DI 0 "register_operand" "=r")
1679 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1680 (match_operand:DI 2 "data_segment_operand" "")))]
1681 "TARGET_CM_EMBMEDANY"
1682 "add\t%1, %%lo(%a2), %0")
1684 (define_insn "embmedany_brsum"
1685 [(set (match_operand:DI 0 "register_operand" "=r")
1686 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
1687 "TARGET_CM_EMBMEDANY"
1690 (define_insn "embmedany_textuhi"
1691 [(set (match_operand:DI 0 "register_operand" "=r")
1692 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
1693 "TARGET_CM_EMBMEDANY && check_pic (1)"
1694 "sethi\t%%uhi(%a1), %0")
1696 (define_insn "embmedany_texthi"
1697 [(set (match_operand:DI 0 "register_operand" "=r")
1698 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
1699 "TARGET_CM_EMBMEDANY && check_pic (1)"
1700 "sethi\t%%hi(%a1), %0")
1702 (define_insn "embmedany_textulo"
1703 [(set (match_operand:DI 0 "register_operand" "=r")
1704 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1705 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
1706 "TARGET_CM_EMBMEDANY"
1707 "or\t%1, %%ulo(%a2), %0")
1709 (define_insn "embmedany_textlo"
1710 [(set (match_operand:DI 0 "register_operand" "=r")
1711 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1712 (match_operand:DI 2 "text_segment_operand" "")))]
1713 "TARGET_CM_EMBMEDANY"
1714 "or\t%1, %%lo(%a2), %0")
1716 ;; Now some patterns to help reload out a bit.
1717 (define_expand "reload_indi"
1718 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1719 (match_operand:DI 1 "immediate_operand" "")
1720 (match_operand:TI 2 "register_operand" "=&r")])]
1722 || TARGET_CM_EMBMEDANY)
1725 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1729 (define_expand "reload_outdi"
1730 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1731 (match_operand:DI 1 "immediate_operand" "")
1732 (match_operand:TI 2 "register_operand" "=&r")])]
1734 || TARGET_CM_EMBMEDANY)
1737 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1741 ;; Split up putting CONSTs and REGs into DI regs when !arch64
1743 [(set (match_operand:DI 0 "register_operand" "")
1744 (match_operand:DI 1 "const_int_operand" ""))]
1745 "! TARGET_ARCH64 && reload_completed"
1746 [(clobber (const_int 0))]
1748 #if HOST_BITS_PER_WIDE_INT == 32
1749 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1750 (INTVAL (operands[1]) < 0) ?
1753 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1756 unsigned int low, high;
1758 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
1759 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
1760 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
1762 /* Slick... but this trick loses if this subreg constant part
1763 can be done in one insn. */
1765 && ! SPARC_SETHI32_P (high)
1766 && ! SPARC_SIMM13_P (high))
1767 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1768 gen_highpart (SImode, operands[0])));
1770 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
1776 [(set (match_operand:DI 0 "register_operand" "")
1777 (match_operand:DI 1 "const_double_operand" ""))]
1781 && ((GET_CODE (operands[0]) == REG
1782 && REGNO (operands[0]) < 32)
1783 || (GET_CODE (operands[0]) == SUBREG
1784 && GET_CODE (SUBREG_REG (operands[0])) == REG
1785 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1786 [(clobber (const_int 0))]
1788 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1789 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
1791 /* Slick... but this trick loses if this subreg constant part
1792 can be done in one insn. */
1793 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
1794 && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
1795 && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
1797 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1798 gen_highpart (SImode, operands[0])));
1802 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1803 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
1809 [(set (match_operand:DI 0 "register_operand" "")
1810 (match_operand:DI 1 "register_operand" ""))]
1814 && ((GET_CODE (operands[0]) == REG
1815 && REGNO (operands[0]) < 32)
1816 || (GET_CODE (operands[0]) == SUBREG
1817 && GET_CODE (SUBREG_REG (operands[0])) == REG
1818 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1819 [(clobber (const_int 0))]
1821 rtx set_dest = operands[0];
1822 rtx set_src = operands[1];
1826 dest1 = gen_highpart (SImode, set_dest);
1827 dest2 = gen_lowpart (SImode, set_dest);
1828 src1 = gen_highpart (SImode, set_src);
1829 src2 = gen_lowpart (SImode, set_src);
1831 /* Now emit using the real source and destination we found, swapping
1832 the order if we detect overlap. */
1833 if (reg_overlap_mentioned_p (dest1, src2))
1835 emit_insn (gen_movsi (dest2, src2));
1836 emit_insn (gen_movsi (dest1, src1));
1840 emit_insn (gen_movsi (dest1, src1));
1841 emit_insn (gen_movsi (dest2, src2));
1846 ;; Now handle the cases of memory moves from/to non-even
1847 ;; DI mode register pairs.
1849 [(set (match_operand:DI 0 "register_operand" "")
1850 (match_operand:DI 1 "memory_operand" ""))]
1853 && sparc_splitdi_legitimate (operands[0], operands[1]))"
1854 [(clobber (const_int 0))]
1856 rtx word0 = adjust_address (operands[1], SImode, 0);
1857 rtx word1 = adjust_address (operands[1], SImode, 4);
1858 rtx high_part = gen_highpart (SImode, operands[0]);
1859 rtx low_part = gen_lowpart (SImode, operands[0]);
1861 if (reg_overlap_mentioned_p (high_part, word1))
1863 emit_insn (gen_movsi (low_part, word1));
1864 emit_insn (gen_movsi (high_part, word0));
1868 emit_insn (gen_movsi (high_part, word0));
1869 emit_insn (gen_movsi (low_part, word1));
1875 [(set (match_operand:DI 0 "memory_operand" "")
1876 (match_operand:DI 1 "register_operand" ""))]
1879 && sparc_splitdi_legitimate (operands[1], operands[0]))"
1880 [(clobber (const_int 0))]
1882 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
1883 gen_highpart (SImode, operands[1])));
1884 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
1885 gen_lowpart (SImode, operands[1])));
1890 [(set (match_operand:DI 0 "memory_operand" "")
1891 (match_operand:DI 1 "const_zero_operand" ""))]
1895 && ! mem_min_alignment (operands[0], 8)))
1896 && offsettable_memref_p (operands[0])"
1897 [(clobber (const_int 0))]
1899 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
1900 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
1905 ;; Floating point and vector move instructions
1907 ;; Yes, you guessed it right, the former movsf expander.
1908 (define_expand "mov<V32:mode>"
1909 [(set (match_operand:V32 0 "nonimmediate_operand" "")
1910 (match_operand:V32 1 "general_operand" ""))]
1911 "<V32:MODE>mode == SFmode || TARGET_VIS"
1913 if (sparc_expand_move (<V32:MODE>mode, operands))
1917 (define_insn "*movsf_insn"
1918 [(set (match_operand:V32 0 "nonimmediate_operand" "=d,d,f,*r,*r,*r,f,*r,m,m")
1919 (match_operand:V32 1 "input_operand" "GY,ZC,f,*rRY,Q,S,m,m,f,*rGY"))]
1921 && (register_operand (operands[0], <V32:MODE>mode)
1922 || register_or_zero_or_all_ones_operand (operands[1], <V32:MODE>mode))"
1924 if (GET_CODE (operands[1]) == CONST_DOUBLE
1925 && (which_alternative == 3
1926 || which_alternative == 4
1927 || which_alternative == 5))
1932 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1933 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1934 operands[1] = GEN_INT (i);
1937 switch (which_alternative)
1940 return "fzeros\t%0";
1944 return "fmovs\t%1, %0";
1946 return "mov\t%1, %0";
1948 return "sethi\t%%hi(%a1), %0";
1953 return "ld\t%1, %0";
1956 return "st\t%r1, %0";
1961 [(set_attr "type" "fga,fga,fpmove,*,*,*,fpload,load,fpstore,store")])
1963 ;; Exactly the same as above, except that all `f' cases are deleted.
1964 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1967 (define_insn "*movsf_insn_no_fpu"
1968 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
1969 (match_operand:SF 1 "input_operand" "rR,Q,S,m,rG"))]
1971 && (register_operand (operands[0], SFmode)
1972 || register_or_zero_operand (operands[1], SFmode))"
1974 if (GET_CODE (operands[1]) == CONST_DOUBLE
1975 && (which_alternative == 0
1976 || which_alternative == 1
1977 || which_alternative == 2))
1982 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1983 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1984 operands[1] = GEN_INT (i);
1987 switch (which_alternative)
1990 return "mov\t%1, %0";
1992 return "sethi\t%%hi(%a1), %0";
1996 return "ld\t%1, %0";
1998 return "st\t%r1, %0";
2003 [(set_attr "type" "*,*,*,load,store")])
2005 ;; The following 3 patterns build SFmode constants in integer registers.
2007 (define_insn "*movsf_lo_sum"
2008 [(set (match_operand:SF 0 "register_operand" "=r")
2009 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2010 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2016 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2017 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2018 operands[2] = GEN_INT (i);
2019 return "or\t%1, %%lo(%a2), %0";
2022 (define_insn "*movsf_high"
2023 [(set (match_operand:SF 0 "register_operand" "=r")
2024 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2030 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2031 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2032 operands[1] = GEN_INT (i);
2033 return "sethi\t%%hi(%1), %0";
2037 [(set (match_operand:SF 0 "register_operand" "")
2038 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2039 "REG_P (operands[0]) && REGNO (operands[0]) < 32"
2040 [(set (match_dup 0) (high:SF (match_dup 1)))
2041 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2043 ;; Yes, you again guessed it right, the former movdf expander.
2044 (define_expand "mov<V64:mode>"
2045 [(set (match_operand:V64 0 "nonimmediate_operand" "")
2046 (match_operand:V64 1 "general_operand" ""))]
2047 "<V64:MODE>mode == DFmode || TARGET_VIS"
2049 if (sparc_expand_move (<V64:MODE>mode, operands))
2053 ;; Be careful, fmovd does not exist when !v9.
2054 (define_insn "*movdf_insn_sp32"
2055 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2056 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2059 && (register_operand (operands[0], DFmode)
2060 || register_or_zero_operand (operands[1], DFmode))"
2072 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2073 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2075 (define_insn "*movdf_insn_sp32_no_fpu"
2076 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2077 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2080 && (register_operand (operands[0], DFmode)
2081 || register_or_zero_operand (operands[1], DFmode))"
2088 [(set_attr "type" "load,store,*,*,*")
2089 (set_attr "length" "*,*,2,2,2")])
2091 ;; We have available v9 double floats but not 64-bit integer registers.
2092 (define_insn "*movdf_insn_sp32_v9"
2093 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,b,e,e,T,W,U,T,f,*r,o")
2094 (match_operand:V64 1 "input_operand" "GY,ZC,e,W#F,GY,e,T,U,o#F,*roGYDF,*rGYf"))]
2098 && (register_operand (operands[0], <V64:MODE>mode)
2099 || register_or_zero_or_all_ones_operand (operands[1], <V64:MODE>mode))"
2112 [(set_attr "type" "fga,fga,fpmove,load,store,store,load,store,*,*,*")
2113 (set_attr "length" "*,*,*,*,*,*,*,*,2,2,2")
2114 (set_attr "fptype" "double,double,double,*,*,*,*,*,*,*,*")])
2116 (define_insn "*movdf_insn_sp32_v9_no_fpu"
2117 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2118 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2122 && (register_operand (operands[0], DFmode)
2123 || register_or_zero_operand (operands[1], DFmode))"
2130 [(set_attr "type" "load,store,store,*,*")
2131 (set_attr "length" "*,*,*,2,2")])
2133 ;; We have available both v9 double floats and 64-bit integer registers.
2134 (define_insn "*movdf_insn_sp64"
2135 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,b,e,e,W,*r,*r,m,*r")
2136 (match_operand:V64 1 "input_operand" "GY,ZC,e,W#F,e,*rGY,m,*rGY,DF"))]
2139 && (register_operand (operands[0], <V64:MODE>mode)
2140 || register_or_zero_or_all_ones_operand (operands[1], <V64:MODE>mode))"
2151 [(set_attr "type" "fga,fga,fpmove,load,store,*,load,store,*")
2152 (set_attr "length" "*,*,*,*,*,*,*,*,2")
2153 (set_attr "fptype" "double,double,double,*,*,*,*,*,*")])
2155 (define_insn "*movdf_insn_sp64_no_fpu"
2156 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2157 (match_operand:DF 1 "input_operand" "r,m,rG"))]
2160 && (register_operand (operands[0], DFmode)
2161 || register_or_zero_operand (operands[1], DFmode))"
2166 [(set_attr "type" "*,load,store")])
2168 ;; This pattern builds V64mode constants in integer registers.
2170 [(set (match_operand:V64 0 "register_operand" "")
2171 (match_operand:V64 1 "const_double_or_vector_operand" ""))]
2173 && (GET_CODE (operands[0]) == REG
2174 && REGNO (operands[0]) < 32)
2175 && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2176 && reload_completed"
2177 [(clobber (const_int 0))]
2179 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2183 #if HOST_BITS_PER_WIDE_INT == 32
2186 enum machine_mode mode = GET_MODE (operands[1]);
2187 rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2188 emit_insn (gen_movdi (operands[0], tem));
2193 enum machine_mode mode = GET_MODE (operands[1]);
2194 rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2195 rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2197 gcc_assert (GET_CODE (hi) == CONST_INT);
2198 gcc_assert (GET_CODE (lo) == CONST_INT);
2200 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2202 /* Slick... but this trick loses if this subreg constant part
2203 can be done in one insn. */
2205 && ! SPARC_SETHI32_P (INTVAL (hi))
2206 && ! SPARC_SIMM13_P (INTVAL (hi)))
2208 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2209 gen_highpart (SImode, operands[0])));
2213 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2219 ;; Ok, now the splits to handle all the multi insn and
2220 ;; mis-aligned memory address cases.
2221 ;; In these splits please take note that we must be
2222 ;; careful when V9 but not ARCH64 because the integer
2223 ;; register DFmode cases must be handled.
2225 [(set (match_operand:V64 0 "register_operand" "")
2226 (match_operand:V64 1 "register_operand" ""))]
2229 && ((GET_CODE (operands[0]) == REG
2230 && REGNO (operands[0]) < 32)
2231 || (GET_CODE (operands[0]) == SUBREG
2232 && GET_CODE (SUBREG_REG (operands[0])) == REG
2233 && REGNO (SUBREG_REG (operands[0])) < 32))))
2234 && reload_completed"
2235 [(clobber (const_int 0))]
2237 rtx set_dest = operands[0];
2238 rtx set_src = operands[1];
2241 enum machine_mode half_mode;
2243 /* We can be expanded for DFmode or integral vector modes. */
2244 if (<V64:MODE>mode == DFmode)
2249 dest1 = gen_highpart (half_mode, set_dest);
2250 dest2 = gen_lowpart (half_mode, set_dest);
2251 src1 = gen_highpart (half_mode, set_src);
2252 src2 = gen_lowpart (half_mode, set_src);
2254 /* Now emit using the real source and destination we found, swapping
2255 the order if we detect overlap. */
2256 if (reg_overlap_mentioned_p (dest1, src2))
2258 emit_move_insn_1 (dest2, src2);
2259 emit_move_insn_1 (dest1, src1);
2263 emit_move_insn_1 (dest1, src1);
2264 emit_move_insn_1 (dest2, src2);
2270 [(set (match_operand:V64 0 "register_operand" "")
2271 (match_operand:V64 1 "memory_operand" ""))]
2274 && (((REGNO (operands[0]) % 2) != 0)
2275 || ! mem_min_alignment (operands[1], 8))
2276 && offsettable_memref_p (operands[1])"
2277 [(clobber (const_int 0))]
2279 enum machine_mode half_mode;
2282 /* We can be expanded for DFmode or integral vector modes. */
2283 if (<V64:MODE>mode == DFmode)
2288 word0 = adjust_address (operands[1], half_mode, 0);
2289 word1 = adjust_address (operands[1], half_mode, 4);
2291 if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
2293 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2294 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2298 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2299 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2305 [(set (match_operand:V64 0 "memory_operand" "")
2306 (match_operand:V64 1 "register_operand" ""))]
2309 && (((REGNO (operands[1]) % 2) != 0)
2310 || ! mem_min_alignment (operands[0], 8))
2311 && offsettable_memref_p (operands[0])"
2312 [(clobber (const_int 0))]
2314 enum machine_mode half_mode;
2317 /* We can be expanded for DFmode or integral vector modes. */
2318 if (<V64:MODE>mode == DFmode)
2323 word0 = adjust_address (operands[0], half_mode, 0);
2324 word1 = adjust_address (operands[0], half_mode, 4);
2326 emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
2327 emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
2332 [(set (match_operand:V64 0 "memory_operand" "")
2333 (match_operand:V64 1 "const_zero_operand" ""))]
2337 && ! mem_min_alignment (operands[0], 8)))
2338 && offsettable_memref_p (operands[0])"
2339 [(clobber (const_int 0))]
2341 enum machine_mode half_mode;
2344 /* We can be expanded for DFmode or integral vector modes. */
2345 if (<V64:MODE>mode == DFmode)
2350 dest1 = adjust_address (operands[0], half_mode, 0);
2351 dest2 = adjust_address (operands[0], half_mode, 4);
2353 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2354 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2359 [(set (match_operand:V64 0 "register_operand" "")
2360 (match_operand:V64 1 "const_zero_operand" ""))]
2363 && ((GET_CODE (operands[0]) == REG
2364 && REGNO (operands[0]) < 32)
2365 || (GET_CODE (operands[0]) == SUBREG
2366 && GET_CODE (SUBREG_REG (operands[0])) == REG
2367 && REGNO (SUBREG_REG (operands[0])) < 32))"
2368 [(clobber (const_int 0))]
2370 enum machine_mode half_mode;
2371 rtx set_dest = operands[0];
2374 /* We can be expanded for DFmode or integral vector modes. */
2375 if (<V64:MODE>mode == DFmode)
2380 dest1 = gen_highpart (half_mode, set_dest);
2381 dest2 = gen_lowpart (half_mode, set_dest);
2382 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2383 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2387 (define_expand "movtf"
2388 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2389 (match_operand:TF 1 "general_operand" ""))]
2392 if (sparc_expand_move (TFmode, operands))
2396 (define_insn "*movtf_insn_sp32"
2397 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2398 (match_operand:TF 1 "input_operand" "G,oe,GeUr,o,roG"))]
2401 && (register_operand (operands[0], TFmode)
2402 || register_or_zero_operand (operands[1], TFmode))"
2404 [(set_attr "length" "4")])
2406 ;; Exactly the same as above, except that all `e' cases are deleted.
2407 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2410 (define_insn "*movtf_insn_sp32_no_fpu"
2411 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2412 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
2415 && (register_operand (operands[0], TFmode)
2416 || register_or_zero_operand (operands[1], TFmode))"
2418 [(set_attr "length" "4")])
2420 (define_insn "*movtf_insn_sp64"
2421 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2422 (match_operand:TF 1 "input_operand" "G,oe,Ger,roG"))]
2425 && ! TARGET_HARD_QUAD
2426 && (register_operand (operands[0], TFmode)
2427 || register_or_zero_operand (operands[1], TFmode))"
2429 [(set_attr "length" "2")])
2431 (define_insn "*movtf_insn_sp64_hq"
2432 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2433 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
2437 && (register_operand (operands[0], TFmode)
2438 || register_or_zero_operand (operands[1], TFmode))"
2446 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2447 (set_attr "length" "2,*,*,*,2,2")])
2449 (define_insn "*movtf_insn_sp64_no_fpu"
2450 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2451 (match_operand:TF 1 "input_operand" "orG,rG"))]
2454 && (register_operand (operands[0], TFmode)
2455 || register_or_zero_operand (operands[1], TFmode))"
2457 [(set_attr "length" "2")])
2459 ;; Now all the splits to handle multi-insn TF mode moves.
2461 [(set (match_operand:TF 0 "register_operand" "")
2462 (match_operand:TF 1 "register_operand" ""))]
2466 && ! TARGET_HARD_QUAD)
2467 || ! fp_register_operand (operands[0], TFmode))"
2468 [(clobber (const_int 0))]
2470 rtx set_dest = operands[0];
2471 rtx set_src = operands[1];
2475 dest1 = gen_df_reg (set_dest, 0);
2476 dest2 = gen_df_reg (set_dest, 1);
2477 src1 = gen_df_reg (set_src, 0);
2478 src2 = gen_df_reg (set_src, 1);
2480 /* Now emit using the real source and destination we found, swapping
2481 the order if we detect overlap. */
2482 if (reg_overlap_mentioned_p (dest1, src2))
2484 emit_insn (gen_movdf (dest2, src2));
2485 emit_insn (gen_movdf (dest1, src1));
2489 emit_insn (gen_movdf (dest1, src1));
2490 emit_insn (gen_movdf (dest2, src2));
2496 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2497 (match_operand:TF 1 "const_zero_operand" ""))]
2499 [(clobber (const_int 0))]
2501 rtx set_dest = operands[0];
2504 switch (GET_CODE (set_dest))
2507 dest1 = gen_df_reg (set_dest, 0);
2508 dest2 = gen_df_reg (set_dest, 1);
2511 dest1 = adjust_address (set_dest, DFmode, 0);
2512 dest2 = adjust_address (set_dest, DFmode, 8);
2518 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2519 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2524 [(set (match_operand:TF 0 "register_operand" "")
2525 (match_operand:TF 1 "memory_operand" ""))]
2527 && offsettable_memref_p (operands[1])
2529 || ! TARGET_HARD_QUAD
2530 || ! fp_register_operand (operands[0], TFmode)))"
2531 [(clobber (const_int 0))]
2533 rtx word0 = adjust_address (operands[1], DFmode, 0);
2534 rtx word1 = adjust_address (operands[1], DFmode, 8);
2535 rtx set_dest, dest1, dest2;
2537 set_dest = operands[0];
2539 dest1 = gen_df_reg (set_dest, 0);
2540 dest2 = gen_df_reg (set_dest, 1);
2542 /* Now output, ordering such that we don't clobber any registers
2543 mentioned in the address. */
2544 if (reg_overlap_mentioned_p (dest1, word1))
2547 emit_insn (gen_movdf (dest2, word1));
2548 emit_insn (gen_movdf (dest1, word0));
2552 emit_insn (gen_movdf (dest1, word0));
2553 emit_insn (gen_movdf (dest2, word1));
2559 [(set (match_operand:TF 0 "memory_operand" "")
2560 (match_operand:TF 1 "register_operand" ""))]
2562 && offsettable_memref_p (operands[0])
2564 || ! TARGET_HARD_QUAD
2565 || ! fp_register_operand (operands[1], TFmode)))"
2566 [(clobber (const_int 0))]
2568 rtx set_src = operands[1];
2570 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2571 gen_df_reg (set_src, 0)));
2572 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2573 gen_df_reg (set_src, 1)));
2578 ;; SPARC-V9 conditional move instructions
2580 ;; We can handle larger constants here for some flavors, but for now we keep
2581 ;; it simple and only allow those constants supported by all flavors.
2582 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2583 ;; 3 contains the constant if one is present, but we handle either for
2584 ;; generality (sparc.c puts a constant in operand 2).
2586 (define_expand "mov<I:mode>cc"
2587 [(set (match_operand:I 0 "register_operand" "")
2588 (if_then_else:I (match_operand 1 "comparison_operator" "")
2589 (match_operand:I 2 "arith10_operand" "")
2590 (match_operand:I 3 "arith10_operand" "")))]
2591 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2593 enum rtx_code code = GET_CODE (operands[1]);
2596 if (GET_MODE (XEXP (operands[1], 0)) == DImode
2600 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2602 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2603 GET_CODE (operands[1]));
2605 if (XEXP (operands[1], 1) == const0_rtx
2606 && GET_CODE (XEXP (operands[1], 0)) == REG
2607 && GET_MODE (XEXP (operands[1], 0)) == DImode
2608 && v9_regcmp_p (code))
2609 cc_reg = XEXP (operands[1], 0);
2611 cc_reg = gen_compare_reg (operands[1]);
2613 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2616 (define_expand "mov<F:mode>cc"
2617 [(set (match_operand:F 0 "register_operand" "")
2618 (if_then_else:F (match_operand 1 "comparison_operator" "")
2619 (match_operand:F 2 "register_operand" "")
2620 (match_operand:F 3 "register_operand" "")))]
2621 "TARGET_V9 && TARGET_FPU"
2623 enum rtx_code code = GET_CODE (operands[1]);
2626 if (GET_MODE (XEXP (operands[1], 0)) == DImode
2630 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2632 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2633 GET_CODE (operands[1]));
2635 if (XEXP (operands[1], 1) == const0_rtx
2636 && GET_CODE (XEXP (operands[1], 0)) == REG
2637 && GET_MODE (XEXP (operands[1], 0)) == DImode
2638 && v9_regcmp_p (code))
2639 cc_reg = XEXP (operands[1], 0);
2641 cc_reg = gen_compare_reg (operands[1]);
2643 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2646 ;; Conditional move define_insns
2648 (define_insn "*mov<I:mode>_cc_v9"
2649 [(set (match_operand:I 0 "register_operand" "=r,r")
2650 (if_then_else:I (match_operator 1 "comparison_operator"
2651 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2653 (match_operand:I 3 "arith11_operand" "rL,0")
2654 (match_operand:I 4 "arith11_operand" "0,rL")))]
2655 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2658 mov%c1\t%x2, %4, %0"
2659 [(set_attr "type" "cmove")])
2661 (define_insn "*mov<I:mode>_cc_reg_sp64"
2662 [(set (match_operand:I 0 "register_operand" "=r,r")
2663 (if_then_else:I (match_operator 1 "v9_register_compare_operator"
2664 [(match_operand:DI 2 "register_operand" "r,r")
2666 (match_operand:I 3 "arith10_operand" "rM,0")
2667 (match_operand:I 4 "arith10_operand" "0,rM")))]
2670 movr%D1\t%2, %r3, %0
2671 movr%d1\t%2, %r4, %0"
2672 [(set_attr "type" "cmove")])
2674 (define_insn "*movsf_cc_v9"
2675 [(set (match_operand:SF 0 "register_operand" "=f,f")
2676 (if_then_else:SF (match_operator 1 "comparison_operator"
2677 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2679 (match_operand:SF 3 "register_operand" "f,0")
2680 (match_operand:SF 4 "register_operand" "0,f")))]
2681 "TARGET_V9 && TARGET_FPU"
2683 fmovs%C1\t%x2, %3, %0
2684 fmovs%c1\t%x2, %4, %0"
2685 [(set_attr "type" "fpcmove")])
2687 (define_insn "*movsf_cc_reg_sp64"
2688 [(set (match_operand:SF 0 "register_operand" "=f,f")
2689 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
2690 [(match_operand:DI 2 "register_operand" "r,r")
2692 (match_operand:SF 3 "register_operand" "f,0")
2693 (match_operand:SF 4 "register_operand" "0,f")))]
2694 "TARGET_ARCH64 && TARGET_FPU"
2696 fmovrs%D1\t%2, %3, %0
2697 fmovrs%d1\t%2, %4, %0"
2698 [(set_attr "type" "fpcrmove")])
2700 ;; Named because invoked by movtf_cc_v9
2701 (define_insn "movdf_cc_v9"
2702 [(set (match_operand:DF 0 "register_operand" "=e,e")
2703 (if_then_else:DF (match_operator 1 "comparison_operator"
2704 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2706 (match_operand:DF 3 "register_operand" "e,0")
2707 (match_operand:DF 4 "register_operand" "0,e")))]
2708 "TARGET_V9 && TARGET_FPU"
2710 fmovd%C1\t%x2, %3, %0
2711 fmovd%c1\t%x2, %4, %0"
2712 [(set_attr "type" "fpcmove")
2713 (set_attr "fptype" "double")])
2715 ;; Named because invoked by movtf_cc_reg_sp64
2716 (define_insn "movdf_cc_reg_sp64"
2717 [(set (match_operand:DF 0 "register_operand" "=e,e")
2718 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
2719 [(match_operand:DI 2 "register_operand" "r,r")
2721 (match_operand:DF 3 "register_operand" "e,0")
2722 (match_operand:DF 4 "register_operand" "0,e")))]
2723 "TARGET_ARCH64 && TARGET_FPU"
2725 fmovrd%D1\t%2, %3, %0
2726 fmovrd%d1\t%2, %4, %0"
2727 [(set_attr "type" "fpcrmove")
2728 (set_attr "fptype" "double")])
2730 (define_insn "*movtf_cc_hq_v9"
2731 [(set (match_operand:TF 0 "register_operand" "=e,e")
2732 (if_then_else:TF (match_operator 1 "comparison_operator"
2733 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2735 (match_operand:TF 3 "register_operand" "e,0")
2736 (match_operand:TF 4 "register_operand" "0,e")))]
2737 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2739 fmovq%C1\t%x2, %3, %0
2740 fmovq%c1\t%x2, %4, %0"
2741 [(set_attr "type" "fpcmove")])
2743 (define_insn "*movtf_cc_reg_hq_sp64"
2744 [(set (match_operand:TF 0 "register_operand" "=e,e")
2745 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2746 [(match_operand:DI 2 "register_operand" "r,r")
2748 (match_operand:TF 3 "register_operand" "e,0")
2749 (match_operand:TF 4 "register_operand" "0,e")))]
2750 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
2752 fmovrq%D1\t%2, %3, %0
2753 fmovrq%d1\t%2, %4, %0"
2754 [(set_attr "type" "fpcrmove")])
2756 (define_insn_and_split "*movtf_cc_v9"
2757 [(set (match_operand:TF 0 "register_operand" "=e,e")
2758 (if_then_else:TF (match_operator 1 "comparison_operator"
2759 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2761 (match_operand:TF 3 "register_operand" "e,0")
2762 (match_operand:TF 4 "register_operand" "0,e")))]
2763 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
2765 "&& reload_completed"
2766 [(clobber (const_int 0))]
2768 rtx set_dest = operands[0];
2769 rtx set_srca = operands[3];
2770 rtx set_srcb = operands[4];
2771 int third = rtx_equal_p (set_dest, set_srca);
2773 rtx srca1, srca2, srcb1, srcb2;
2775 dest1 = gen_df_reg (set_dest, 0);
2776 dest2 = gen_df_reg (set_dest, 1);
2777 srca1 = gen_df_reg (set_srca, 0);
2778 srca2 = gen_df_reg (set_srca, 1);
2779 srcb1 = gen_df_reg (set_srcb, 0);
2780 srcb2 = gen_df_reg (set_srcb, 1);
2782 /* Now emit using the real source and destination we found, swapping
2783 the order if we detect overlap. */
2784 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2785 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2787 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2788 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2792 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2793 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2797 [(set_attr "length" "2")])
2799 (define_insn_and_split "*movtf_cc_reg_sp64"
2800 [(set (match_operand:TF 0 "register_operand" "=e,e")
2801 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2802 [(match_operand:DI 2 "register_operand" "r,r")
2804 (match_operand:TF 3 "register_operand" "e,0")
2805 (match_operand:TF 4 "register_operand" "0,e")))]
2806 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
2808 "&& reload_completed"
2809 [(clobber (const_int 0))]
2811 rtx set_dest = operands[0];
2812 rtx set_srca = operands[3];
2813 rtx set_srcb = operands[4];
2814 int third = rtx_equal_p (set_dest, set_srca);
2816 rtx srca1, srca2, srcb1, srcb2;
2818 dest1 = gen_df_reg (set_dest, 0);
2819 dest2 = gen_df_reg (set_dest, 1);
2820 srca1 = gen_df_reg (set_srca, 0);
2821 srca2 = gen_df_reg (set_srca, 1);
2822 srcb1 = gen_df_reg (set_srcb, 0);
2823 srcb2 = gen_df_reg (set_srcb, 1);
2825 /* Now emit using the real source and destination we found, swapping
2826 the order if we detect overlap. */
2827 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2828 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2830 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2831 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2835 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2836 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2840 [(set_attr "length" "2")])
2843 ;; Zero-extension instructions
2845 ;; These patterns originally accepted general_operands, however, slightly
2846 ;; better code is generated by only accepting register_operands, and then
2847 ;; letting combine generate the ldu[hb] insns.
2849 (define_expand "zero_extendhisi2"
2850 [(set (match_operand:SI 0 "register_operand" "")
2851 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2854 rtx temp = gen_reg_rtx (SImode);
2855 rtx shift_16 = GEN_INT (16);
2856 int op1_subbyte = 0;
2858 if (GET_CODE (operand1) == SUBREG)
2860 op1_subbyte = SUBREG_BYTE (operand1);
2861 op1_subbyte /= GET_MODE_SIZE (SImode);
2862 op1_subbyte *= GET_MODE_SIZE (SImode);
2863 operand1 = XEXP (operand1, 0);
2866 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2868 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2872 (define_insn "*zero_extendhisi2_insn"
2873 [(set (match_operand:SI 0 "register_operand" "=r")
2874 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2877 [(set_attr "type" "load")
2878 (set_attr "us3load_type" "3cycle")])
2880 (define_expand "zero_extendqihi2"
2881 [(set (match_operand:HI 0 "register_operand" "")
2882 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2886 (define_insn "*zero_extendqihi2_insn"
2887 [(set (match_operand:HI 0 "register_operand" "=r,r")
2888 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
2889 "GET_CODE (operands[1]) != CONST_INT"
2893 [(set_attr "type" "*,load")
2894 (set_attr "us3load_type" "*,3cycle")])
2896 (define_expand "zero_extendqisi2"
2897 [(set (match_operand:SI 0 "register_operand" "")
2898 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2902 (define_insn "*zero_extendqisi2_insn"
2903 [(set (match_operand:SI 0 "register_operand" "=r,r")
2904 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
2905 "GET_CODE (operands[1]) != CONST_INT"
2909 [(set_attr "type" "*,load")
2910 (set_attr "us3load_type" "*,3cycle")])
2912 (define_expand "zero_extendqidi2"
2913 [(set (match_operand:DI 0 "register_operand" "")
2914 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2918 (define_insn "*zero_extendqidi2_insn"
2919 [(set (match_operand:DI 0 "register_operand" "=r,r")
2920 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
2921 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2925 [(set_attr "type" "*,load")
2926 (set_attr "us3load_type" "*,3cycle")])
2928 (define_expand "zero_extendhidi2"
2929 [(set (match_operand:DI 0 "register_operand" "")
2930 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2933 rtx temp = gen_reg_rtx (DImode);
2934 rtx shift_48 = GEN_INT (48);
2935 int op1_subbyte = 0;
2937 if (GET_CODE (operand1) == SUBREG)
2939 op1_subbyte = SUBREG_BYTE (operand1);
2940 op1_subbyte /= GET_MODE_SIZE (DImode);
2941 op1_subbyte *= GET_MODE_SIZE (DImode);
2942 operand1 = XEXP (operand1, 0);
2945 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
2947 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
2951 (define_insn "*zero_extendhidi2_insn"
2952 [(set (match_operand:DI 0 "register_operand" "=r")
2953 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2956 [(set_attr "type" "load")
2957 (set_attr "us3load_type" "3cycle")])
2959 ;; ??? Write truncdisi pattern using sra?
2961 (define_expand "zero_extendsidi2"
2962 [(set (match_operand:DI 0 "register_operand" "")
2963 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
2967 (define_insn "*zero_extendsidi2_insn_sp64"
2968 [(set (match_operand:DI 0 "register_operand" "=r,r")
2969 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
2970 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2974 [(set_attr "type" "shift,load")])
2976 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
2977 [(set (match_operand:DI 0 "register_operand" "=r")
2978 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
2981 "&& reload_completed"
2982 [(set (match_dup 2) (match_dup 3))
2983 (set (match_dup 4) (match_dup 5))]
2987 dest1 = gen_highpart (SImode, operands[0]);
2988 dest2 = gen_lowpart (SImode, operands[0]);
2990 /* Swap the order in case of overlap. */
2991 if (REGNO (dest1) == REGNO (operands[1]))
2993 operands[2] = dest2;
2994 operands[3] = operands[1];
2995 operands[4] = dest1;
2996 operands[5] = const0_rtx;
3000 operands[2] = dest1;
3001 operands[3] = const0_rtx;
3002 operands[4] = dest2;
3003 operands[5] = operands[1];
3006 [(set_attr "length" "2")])
3008 ;; Simplify comparisons of extended values.
3010 (define_insn "*cmp_zero_extendqisi2"
3011 [(set (reg:CC CC_REG)
3012 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3015 "andcc\t%0, 0xff, %%g0"
3016 [(set_attr "type" "compare")])
3018 (define_insn "*cmp_zero_qi"
3019 [(set (reg:CC CC_REG)
3020 (compare:CC (match_operand:QI 0 "register_operand" "r")
3023 "andcc\t%0, 0xff, %%g0"
3024 [(set_attr "type" "compare")])
3026 (define_insn "*cmp_zero_extendqisi2_set"
3027 [(set (reg:CC CC_REG)
3028 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3030 (set (match_operand:SI 0 "register_operand" "=r")
3031 (zero_extend:SI (match_dup 1)))]
3033 "andcc\t%1, 0xff, %0"
3034 [(set_attr "type" "compare")])
3036 (define_insn "*cmp_zero_extendqisi2_andcc_set"
3037 [(set (reg:CC CC_REG)
3038 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3041 (set (match_operand:SI 0 "register_operand" "=r")
3042 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3044 "andcc\t%1, 0xff, %0"
3045 [(set_attr "type" "compare")])
3047 (define_insn "*cmp_zero_extendqidi2"
3048 [(set (reg:CCX CC_REG)
3049 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3052 "andcc\t%0, 0xff, %%g0"
3053 [(set_attr "type" "compare")])
3055 (define_insn "*cmp_zero_qi_sp64"
3056 [(set (reg:CCX CC_REG)
3057 (compare:CCX (match_operand:QI 0 "register_operand" "r")
3060 "andcc\t%0, 0xff, %%g0"
3061 [(set_attr "type" "compare")])
3063 (define_insn "*cmp_zero_extendqidi2_set"
3064 [(set (reg:CCX CC_REG)
3065 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3067 (set (match_operand:DI 0 "register_operand" "=r")
3068 (zero_extend:DI (match_dup 1)))]
3070 "andcc\t%1, 0xff, %0"
3071 [(set_attr "type" "compare")])
3073 (define_insn "*cmp_zero_extendqidi2_andcc_set"
3074 [(set (reg:CCX CC_REG)
3075 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3078 (set (match_operand:DI 0 "register_operand" "=r")
3079 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3081 "andcc\t%1, 0xff, %0"
3082 [(set_attr "type" "compare")])
3084 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3086 (define_insn "*cmp_siqi_trunc"
3087 [(set (reg:CC CC_REG)
3088 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3091 "andcc\t%0, 0xff, %%g0"
3092 [(set_attr "type" "compare")])
3094 (define_insn "*cmp_siqi_trunc_set"
3095 [(set (reg:CC CC_REG)
3096 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3098 (set (match_operand:QI 0 "register_operand" "=r")
3099 (subreg:QI (match_dup 1) 3))]
3101 "andcc\t%1, 0xff, %0"
3102 [(set_attr "type" "compare")])
3104 (define_insn "*cmp_diqi_trunc"
3105 [(set (reg:CC CC_REG)
3106 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3109 "andcc\t%0, 0xff, %%g0"
3110 [(set_attr "type" "compare")])
3112 (define_insn "*cmp_diqi_trunc_set"
3113 [(set (reg:CC CC_REG)
3114 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3116 (set (match_operand:QI 0 "register_operand" "=r")
3117 (subreg:QI (match_dup 1) 7))]
3119 "andcc\t%1, 0xff, %0"
3120 [(set_attr "type" "compare")])
3123 ;; Sign-extension instructions
3125 ;; These patterns originally accepted general_operands, however, slightly
3126 ;; better code is generated by only accepting register_operands, and then
3127 ;; letting combine generate the lds[hb] insns.
3129 (define_expand "extendhisi2"
3130 [(set (match_operand:SI 0 "register_operand" "")
3131 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3134 rtx temp = gen_reg_rtx (SImode);
3135 rtx shift_16 = GEN_INT (16);
3136 int op1_subbyte = 0;
3138 if (GET_CODE (operand1) == SUBREG)
3140 op1_subbyte = SUBREG_BYTE (operand1);
3141 op1_subbyte /= GET_MODE_SIZE (SImode);
3142 op1_subbyte *= GET_MODE_SIZE (SImode);
3143 operand1 = XEXP (operand1, 0);
3146 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3148 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3152 (define_insn "*sign_extendhisi2_insn"
3153 [(set (match_operand:SI 0 "register_operand" "=r")
3154 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3157 [(set_attr "type" "sload")
3158 (set_attr "us3load_type" "3cycle")])
3160 (define_expand "extendqihi2"
3161 [(set (match_operand:HI 0 "register_operand" "")
3162 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3165 rtx temp = gen_reg_rtx (SImode);
3166 rtx shift_24 = GEN_INT (24);
3167 int op1_subbyte = 0;
3168 int op0_subbyte = 0;
3170 if (GET_CODE (operand1) == SUBREG)
3172 op1_subbyte = SUBREG_BYTE (operand1);
3173 op1_subbyte /= GET_MODE_SIZE (SImode);
3174 op1_subbyte *= GET_MODE_SIZE (SImode);
3175 operand1 = XEXP (operand1, 0);
3177 if (GET_CODE (operand0) == SUBREG)
3179 op0_subbyte = SUBREG_BYTE (operand0);
3180 op0_subbyte /= GET_MODE_SIZE (SImode);
3181 op0_subbyte *= GET_MODE_SIZE (SImode);
3182 operand0 = XEXP (operand0, 0);
3184 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3186 if (GET_MODE (operand0) != SImode)
3187 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3188 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3192 (define_insn "*sign_extendqihi2_insn"
3193 [(set (match_operand:HI 0 "register_operand" "=r")
3194 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3197 [(set_attr "type" "sload")
3198 (set_attr "us3load_type" "3cycle")])
3200 (define_expand "extendqisi2"
3201 [(set (match_operand:SI 0 "register_operand" "")
3202 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3205 rtx temp = gen_reg_rtx (SImode);
3206 rtx shift_24 = GEN_INT (24);
3207 int op1_subbyte = 0;
3209 if (GET_CODE (operand1) == SUBREG)
3211 op1_subbyte = SUBREG_BYTE (operand1);
3212 op1_subbyte /= GET_MODE_SIZE (SImode);
3213 op1_subbyte *= GET_MODE_SIZE (SImode);
3214 operand1 = XEXP (operand1, 0);
3217 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3219 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3223 (define_insn "*sign_extendqisi2_insn"
3224 [(set (match_operand:SI 0 "register_operand" "=r")
3225 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3228 [(set_attr "type" "sload")
3229 (set_attr "us3load_type" "3cycle")])
3231 (define_expand "extendqidi2"
3232 [(set (match_operand:DI 0 "register_operand" "")
3233 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3236 rtx temp = gen_reg_rtx (DImode);
3237 rtx shift_56 = GEN_INT (56);
3238 int op1_subbyte = 0;
3240 if (GET_CODE (operand1) == SUBREG)
3242 op1_subbyte = SUBREG_BYTE (operand1);
3243 op1_subbyte /= GET_MODE_SIZE (DImode);
3244 op1_subbyte *= GET_MODE_SIZE (DImode);
3245 operand1 = XEXP (operand1, 0);
3248 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3250 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3254 (define_insn "*sign_extendqidi2_insn"
3255 [(set (match_operand:DI 0 "register_operand" "=r")
3256 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3259 [(set_attr "type" "sload")
3260 (set_attr "us3load_type" "3cycle")])
3262 (define_expand "extendhidi2"
3263 [(set (match_operand:DI 0 "register_operand" "")
3264 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3267 rtx temp = gen_reg_rtx (DImode);
3268 rtx shift_48 = GEN_INT (48);
3269 int op1_subbyte = 0;
3271 if (GET_CODE (operand1) == SUBREG)
3273 op1_subbyte = SUBREG_BYTE (operand1);
3274 op1_subbyte /= GET_MODE_SIZE (DImode);
3275 op1_subbyte *= GET_MODE_SIZE (DImode);
3276 operand1 = XEXP (operand1, 0);
3279 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3281 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3285 (define_insn "*sign_extendhidi2_insn"
3286 [(set (match_operand:DI 0 "register_operand" "=r")
3287 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3290 [(set_attr "type" "sload")
3291 (set_attr "us3load_type" "3cycle")])
3293 (define_expand "extendsidi2"
3294 [(set (match_operand:DI 0 "register_operand" "")
3295 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3299 (define_insn "*sign_extendsidi2_insn"
3300 [(set (match_operand:DI 0 "register_operand" "=r,r")
3301 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3306 [(set_attr "type" "shift,sload")
3307 (set_attr "us3load_type" "*,3cycle")])
3310 ;; Special pattern for optimizing bit-field compares. This is needed
3311 ;; because combine uses this as a canonical form.
3313 (define_insn "*cmp_zero_extract"
3314 [(set (reg:CC CC_REG)
3316 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3317 (match_operand:SI 1 "small_int_operand" "I")
3318 (match_operand:SI 2 "small_int_operand" "I"))
3320 "INTVAL (operands[2]) > 19"
3322 int len = INTVAL (operands[1]);
3323 int pos = 32 - INTVAL (operands[2]) - len;
3324 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3325 operands[1] = GEN_INT (mask);
3326 return "andcc\t%0, %1, %%g0";
3328 [(set_attr "type" "compare")])
3330 (define_insn "*cmp_zero_extract_sp64"
3331 [(set (reg:CCX CC_REG)
3333 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3334 (match_operand:SI 1 "small_int_operand" "I")
3335 (match_operand:SI 2 "small_int_operand" "I"))
3337 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3339 int len = INTVAL (operands[1]);
3340 int pos = 64 - INTVAL (operands[2]) - len;
3341 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3342 operands[1] = GEN_INT (mask);
3343 return "andcc\t%0, %1, %%g0";
3345 [(set_attr "type" "compare")])
3348 ;; Conversions between float, double and long double.
3350 (define_insn "extendsfdf2"
3351 [(set (match_operand:DF 0 "register_operand" "=e")
3353 (match_operand:SF 1 "register_operand" "f")))]
3356 [(set_attr "type" "fp")
3357 (set_attr "fptype" "double")])
3359 (define_expand "extendsftf2"
3360 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3362 (match_operand:SF 1 "register_operand" "")))]
3363 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3364 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3366 (define_insn "*extendsftf2_hq"
3367 [(set (match_operand:TF 0 "register_operand" "=e")
3369 (match_operand:SF 1 "register_operand" "f")))]
3370 "TARGET_FPU && TARGET_HARD_QUAD"
3372 [(set_attr "type" "fp")])
3374 (define_expand "extenddftf2"
3375 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3377 (match_operand:DF 1 "register_operand" "")))]
3378 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3379 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3381 (define_insn "*extenddftf2_hq"
3382 [(set (match_operand:TF 0 "register_operand" "=e")
3384 (match_operand:DF 1 "register_operand" "e")))]
3385 "TARGET_FPU && TARGET_HARD_QUAD"
3387 [(set_attr "type" "fp")])
3389 (define_insn "truncdfsf2"
3390 [(set (match_operand:SF 0 "register_operand" "=f")
3392 (match_operand:DF 1 "register_operand" "e")))]
3395 [(set_attr "type" "fp")
3396 (set_attr "fptype" "double")])
3398 (define_expand "trunctfsf2"
3399 [(set (match_operand:SF 0 "register_operand" "")
3401 (match_operand:TF 1 "general_operand" "")))]
3402 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3403 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3405 (define_insn "*trunctfsf2_hq"
3406 [(set (match_operand:SF 0 "register_operand" "=f")
3408 (match_operand:TF 1 "register_operand" "e")))]
3409 "TARGET_FPU && TARGET_HARD_QUAD"
3411 [(set_attr "type" "fp")])
3413 (define_expand "trunctfdf2"
3414 [(set (match_operand:DF 0 "register_operand" "")
3416 (match_operand:TF 1 "general_operand" "")))]
3417 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3418 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3420 (define_insn "*trunctfdf2_hq"
3421 [(set (match_operand:DF 0 "register_operand" "=e")
3423 (match_operand:TF 1 "register_operand" "e")))]
3424 "TARGET_FPU && TARGET_HARD_QUAD"
3426 [(set_attr "type" "fp")])
3429 ;; Conversion between fixed point and floating point.
3431 (define_insn "floatsisf2"
3432 [(set (match_operand:SF 0 "register_operand" "=f")
3433 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3436 [(set_attr "type" "fp")
3437 (set_attr "fptype" "double")])
3439 (define_insn "floatsidf2"
3440 [(set (match_operand:DF 0 "register_operand" "=e")
3441 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3444 [(set_attr "type" "fp")
3445 (set_attr "fptype" "double")])
3447 (define_expand "floatsitf2"
3448 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3449 (float:TF (match_operand:SI 1 "register_operand" "")))]
3450 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3451 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3453 (define_insn "*floatsitf2_hq"
3454 [(set (match_operand:TF 0 "register_operand" "=e")
3455 (float:TF (match_operand:SI 1 "register_operand" "f")))]
3456 "TARGET_FPU && TARGET_HARD_QUAD"
3458 [(set_attr "type" "fp")])
3460 (define_expand "floatunssitf2"
3461 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3462 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3463 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3464 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3466 ;; Now the same for 64 bit sources.
3468 (define_insn "floatdisf2"
3469 [(set (match_operand:SF 0 "register_operand" "=f")
3470 (float:SF (match_operand:DI 1 "register_operand" "e")))]
3471 "TARGET_V9 && TARGET_FPU"
3473 [(set_attr "type" "fp")
3474 (set_attr "fptype" "double")])
3476 (define_expand "floatunsdisf2"
3477 [(use (match_operand:SF 0 "register_operand" ""))
3478 (use (match_operand:DI 1 "general_operand" ""))]
3479 "TARGET_ARCH64 && TARGET_FPU"
3480 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3482 (define_insn "floatdidf2"
3483 [(set (match_operand:DF 0 "register_operand" "=e")
3484 (float:DF (match_operand:DI 1 "register_operand" "e")))]
3485 "TARGET_V9 && TARGET_FPU"
3487 [(set_attr "type" "fp")
3488 (set_attr "fptype" "double")])
3490 (define_expand "floatunsdidf2"
3491 [(use (match_operand:DF 0 "register_operand" ""))
3492 (use (match_operand:DI 1 "general_operand" ""))]
3493 "TARGET_ARCH64 && TARGET_FPU"
3494 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3496 (define_expand "floatditf2"
3497 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3498 (float:TF (match_operand:DI 1 "register_operand" "")))]
3499 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3500 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3502 (define_insn "*floatditf2_hq"
3503 [(set (match_operand:TF 0 "register_operand" "=e")
3504 (float:TF (match_operand:DI 1 "register_operand" "e")))]
3505 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3507 [(set_attr "type" "fp")])
3509 (define_expand "floatunsditf2"
3510 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3511 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3512 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3513 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3515 ;; Convert a float to an actual integer.
3516 ;; Truncation is performed as part of the conversion.
3518 (define_insn "fix_truncsfsi2"
3519 [(set (match_operand:SI 0 "register_operand" "=f")
3520 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3523 [(set_attr "type" "fp")
3524 (set_attr "fptype" "double")])
3526 (define_insn "fix_truncdfsi2"
3527 [(set (match_operand:SI 0 "register_operand" "=f")
3528 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3531 [(set_attr "type" "fp")
3532 (set_attr "fptype" "double")])
3534 (define_expand "fix_trunctfsi2"
3535 [(set (match_operand:SI 0 "register_operand" "")
3536 (fix:SI (match_operand:TF 1 "general_operand" "")))]
3537 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3538 "emit_tfmode_cvt (FIX, operands); DONE;")
3540 (define_insn "*fix_trunctfsi2_hq"
3541 [(set (match_operand:SI 0 "register_operand" "=f")
3542 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
3543 "TARGET_FPU && TARGET_HARD_QUAD"
3545 [(set_attr "type" "fp")])
3547 (define_expand "fixuns_trunctfsi2"
3548 [(set (match_operand:SI 0 "register_operand" "")
3549 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
3550 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3551 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3553 ;; Now the same, for V9 targets
3555 (define_insn "fix_truncsfdi2"
3556 [(set (match_operand:DI 0 "register_operand" "=e")
3557 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3558 "TARGET_V9 && TARGET_FPU"
3560 [(set_attr "type" "fp")
3561 (set_attr "fptype" "double")])
3563 (define_expand "fixuns_truncsfdi2"
3564 [(use (match_operand:DI 0 "register_operand" ""))
3565 (use (match_operand:SF 1 "general_operand" ""))]
3566 "TARGET_ARCH64 && TARGET_FPU"
3567 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
3569 (define_insn "fix_truncdfdi2"
3570 [(set (match_operand:DI 0 "register_operand" "=e")
3571 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3572 "TARGET_V9 && TARGET_FPU"
3574 [(set_attr "type" "fp")
3575 (set_attr "fptype" "double")])
3577 (define_expand "fixuns_truncdfdi2"
3578 [(use (match_operand:DI 0 "register_operand" ""))
3579 (use (match_operand:DF 1 "general_operand" ""))]
3580 "TARGET_ARCH64 && TARGET_FPU"
3581 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
3583 (define_expand "fix_trunctfdi2"
3584 [(set (match_operand:DI 0 "register_operand" "")
3585 (fix:DI (match_operand:TF 1 "general_operand" "")))]
3586 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3587 "emit_tfmode_cvt (FIX, operands); DONE;")
3589 (define_insn "*fix_trunctfdi2_hq"
3590 [(set (match_operand:DI 0 "register_operand" "=e")
3591 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
3592 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3594 [(set_attr "type" "fp")])
3596 (define_expand "fixuns_trunctfdi2"
3597 [(set (match_operand:DI 0 "register_operand" "")
3598 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
3599 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3600 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3603 ;; Integer addition/subtraction instructions.
3605 (define_expand "adddi3"
3606 [(set (match_operand:DI 0 "register_operand" "")
3607 (plus:DI (match_operand:DI 1 "register_operand" "")
3608 (match_operand:DI 2 "arith_double_add_operand" "")))]
3611 if (! TARGET_ARCH64)
3613 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3614 gen_rtx_SET (VOIDmode, operands[0],
3615 gen_rtx_PLUS (DImode, operands[1],
3617 gen_rtx_CLOBBER (VOIDmode,
3618 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3623 (define_insn_and_split "*adddi3_insn_sp32"
3624 [(set (match_operand:DI 0 "register_operand" "=r")
3625 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3626 (match_operand:DI 2 "arith_double_operand" "rHI")))
3627 (clobber (reg:CC CC_REG))]
3630 "&& reload_completed"
3631 [(parallel [(set (reg:CC_NOOV CC_REG)
3632 (compare:CC_NOOV (plus:SI (match_dup 4)
3636 (plus:SI (match_dup 4) (match_dup 5)))])
3638 (plus:SI (plus:SI (match_dup 7)
3640 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3642 operands[3] = gen_lowpart (SImode, operands[0]);
3643 operands[4] = gen_lowpart (SImode, operands[1]);
3644 operands[5] = gen_lowpart (SImode, operands[2]);
3645 operands[6] = gen_highpart (SImode, operands[0]);
3646 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3647 #if HOST_BITS_PER_WIDE_INT == 32
3648 if (GET_CODE (operands[2]) == CONST_INT)
3650 if (INTVAL (operands[2]) < 0)
3651 operands[8] = constm1_rtx;
3653 operands[8] = const0_rtx;
3657 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3659 [(set_attr "length" "2")])
3661 ;; LTU here means "carry set"
3663 [(set (match_operand:SI 0 "register_operand" "=r")
3664 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3665 (match_operand:SI 2 "arith_operand" "rI"))
3666 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3669 [(set_attr "type" "ialuX")])
3671 (define_insn_and_split "*addx_extend_sp32"
3672 [(set (match_operand:DI 0 "register_operand" "=r")
3673 (zero_extend:DI (plus:SI (plus:SI
3674 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3675 (match_operand:SI 2 "arith_operand" "rI"))
3676 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3679 "&& reload_completed"
3680 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
3681 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3682 (set (match_dup 4) (const_int 0))]
3683 "operands[3] = gen_lowpart (SImode, operands[0]);
3684 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
3685 [(set_attr "length" "2")])
3687 (define_insn "*addx_extend_sp64"
3688 [(set (match_operand:DI 0 "register_operand" "=r")
3689 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3690 (match_operand:SI 2 "arith_operand" "rI"))
3691 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3694 [(set_attr "type" "ialuX")])
3696 (define_insn_and_split "*adddi3_extend_sp32"
3697 [(set (match_operand:DI 0 "register_operand" "=r")
3698 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3699 (match_operand:DI 2 "register_operand" "r")))
3700 (clobber (reg:CC CC_REG))]
3703 "&& reload_completed"
3704 [(parallel [(set (reg:CC_NOOV CC_REG)
3705 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
3707 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
3709 (plus:SI (plus:SI (match_dup 4) (const_int 0))
3710 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3711 "operands[3] = gen_lowpart (SImode, operands[2]);
3712 operands[4] = gen_highpart (SImode, operands[2]);
3713 operands[5] = gen_lowpart (SImode, operands[0]);
3714 operands[6] = gen_highpart (SImode, operands[0]);"
3715 [(set_attr "length" "2")])
3717 (define_insn "*adddi3_sp64"
3718 [(set (match_operand:DI 0 "register_operand" "=r,r")
3719 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3720 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3726 (define_insn "addsi3"
3727 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3728 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
3729 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3734 fpadd32s\t%1, %2, %0"
3735 [(set_attr "type" "*,*,fga")
3736 (set_attr "fptype" "*,*,single")])
3738 (define_insn "*cmp_cc_plus"
3739 [(set (reg:CC_NOOV CC_REG)
3740 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3741 (match_operand:SI 1 "arith_operand" "rI"))
3744 "addcc\t%0, %1, %%g0"
3745 [(set_attr "type" "compare")])
3747 (define_insn "*cmp_ccx_plus"
3748 [(set (reg:CCX_NOOV CC_REG)
3749 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
3750 (match_operand:DI 1 "arith_operand" "rI"))
3753 "addcc\t%0, %1, %%g0"
3754 [(set_attr "type" "compare")])
3756 (define_insn "*cmp_cc_plus_set"
3757 [(set (reg:CC_NOOV CC_REG)
3758 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3759 (match_operand:SI 2 "arith_operand" "rI"))
3761 (set (match_operand:SI 0 "register_operand" "=r")
3762 (plus:SI (match_dup 1) (match_dup 2)))]
3765 [(set_attr "type" "compare")])
3767 (define_insn "*cmp_ccx_plus_set"
3768 [(set (reg:CCX_NOOV CC_REG)
3769 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
3770 (match_operand:DI 2 "arith_operand" "rI"))
3772 (set (match_operand:DI 0 "register_operand" "=r")
3773 (plus:DI (match_dup 1) (match_dup 2)))]
3776 [(set_attr "type" "compare")])
3778 (define_expand "subdi3"
3779 [(set (match_operand:DI 0 "register_operand" "")
3780 (minus:DI (match_operand:DI 1 "register_operand" "")
3781 (match_operand:DI 2 "arith_double_add_operand" "")))]
3784 if (! TARGET_ARCH64)
3786 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3787 gen_rtx_SET (VOIDmode, operands[0],
3788 gen_rtx_MINUS (DImode, operands[1],
3790 gen_rtx_CLOBBER (VOIDmode,
3791 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3796 (define_insn_and_split "*subdi3_insn_sp32"
3797 [(set (match_operand:DI 0 "register_operand" "=r")
3798 (minus:DI (match_operand:DI 1 "register_operand" "r")
3799 (match_operand:DI 2 "arith_double_operand" "rHI")))
3800 (clobber (reg:CC CC_REG))]
3803 "&& reload_completed"
3804 [(parallel [(set (reg:CC_NOOV CC_REG)
3805 (compare:CC_NOOV (minus:SI (match_dup 4)
3809 (minus:SI (match_dup 4) (match_dup 5)))])
3811 (minus:SI (minus:SI (match_dup 7)
3813 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3815 operands[3] = gen_lowpart (SImode, operands[0]);
3816 operands[4] = gen_lowpart (SImode, operands[1]);
3817 operands[5] = gen_lowpart (SImode, operands[2]);
3818 operands[6] = gen_highpart (SImode, operands[0]);
3819 operands[7] = gen_highpart (SImode, operands[1]);
3820 #if HOST_BITS_PER_WIDE_INT == 32
3821 if (GET_CODE (operands[2]) == CONST_INT)
3823 if (INTVAL (operands[2]) < 0)
3824 operands[8] = constm1_rtx;
3826 operands[8] = const0_rtx;
3830 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3832 [(set_attr "length" "2")])
3834 ;; LTU here means "carry set"
3836 [(set (match_operand:SI 0 "register_operand" "=r")
3837 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3838 (match_operand:SI 2 "arith_operand" "rI"))
3839 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3842 [(set_attr "type" "ialuX")])
3844 (define_insn "*subx_extend_sp64"
3845 [(set (match_operand:DI 0 "register_operand" "=r")
3846 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3847 (match_operand:SI 2 "arith_operand" "rI"))
3848 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3851 [(set_attr "type" "ialuX")])
3853 (define_insn_and_split "*subx_extend"
3854 [(set (match_operand:DI 0 "register_operand" "=r")
3855 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3856 (match_operand:SI 2 "arith_operand" "rI"))
3857 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3860 "&& reload_completed"
3861 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
3862 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3863 (set (match_dup 4) (const_int 0))]
3864 "operands[3] = gen_lowpart (SImode, operands[0]);
3865 operands[4] = gen_highpart (SImode, operands[0]);"
3866 [(set_attr "length" "2")])
3868 (define_insn_and_split "*subdi3_extend_sp32"
3869 [(set (match_operand:DI 0 "register_operand" "=r")
3870 (minus:DI (match_operand:DI 1 "register_operand" "r")
3871 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
3872 (clobber (reg:CC CC_REG))]
3875 "&& reload_completed"
3876 [(parallel [(set (reg:CC_NOOV CC_REG)
3877 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
3879 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
3881 (minus:SI (minus:SI (match_dup 4) (const_int 0))
3882 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3883 "operands[3] = gen_lowpart (SImode, operands[1]);
3884 operands[4] = gen_highpart (SImode, operands[1]);
3885 operands[5] = gen_lowpart (SImode, operands[0]);
3886 operands[6] = gen_highpart (SImode, operands[0]);"
3887 [(set_attr "length" "2")])
3889 (define_insn "*subdi3_sp64"
3890 [(set (match_operand:DI 0 "register_operand" "=r,r")
3891 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
3892 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3898 (define_insn "subsi3"
3899 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3900 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
3901 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3906 fpsub32s\t%1, %2, %0"
3907 [(set_attr "type" "*,*,fga")
3908 (set_attr "fptype" "*,*,single")])
3910 (define_insn "*cmp_minus_cc"
3911 [(set (reg:CC_NOOV CC_REG)
3912 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
3913 (match_operand:SI 1 "arith_operand" "rI"))
3916 "subcc\t%r0, %1, %%g0"
3917 [(set_attr "type" "compare")])
3919 (define_insn "*cmp_minus_ccx"
3920 [(set (reg:CCX_NOOV CC_REG)
3921 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
3922 (match_operand:DI 1 "arith_operand" "rI"))
3925 "subcc\t%0, %1, %%g0"
3926 [(set_attr "type" "compare")])
3928 (define_insn "cmp_minus_cc_set"
3929 [(set (reg:CC_NOOV CC_REG)
3930 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3931 (match_operand:SI 2 "arith_operand" "rI"))
3933 (set (match_operand:SI 0 "register_operand" "=r")
3934 (minus:SI (match_dup 1) (match_dup 2)))]
3936 "subcc\t%r1, %2, %0"
3937 [(set_attr "type" "compare")])
3939 (define_insn "*cmp_minus_ccx_set"
3940 [(set (reg:CCX_NOOV CC_REG)
3941 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
3942 (match_operand:DI 2 "arith_operand" "rI"))
3944 (set (match_operand:DI 0 "register_operand" "=r")
3945 (minus:DI (match_dup 1) (match_dup 2)))]
3948 [(set_attr "type" "compare")])
3951 ;; Integer multiply/divide instructions.
3953 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
3954 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
3956 (define_insn "mulsi3"
3957 [(set (match_operand:SI 0 "register_operand" "=r")
3958 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3959 (match_operand:SI 2 "arith_operand" "rI")))]
3962 [(set_attr "type" "imul")])
3964 (define_expand "muldi3"
3965 [(set (match_operand:DI 0 "register_operand" "")
3966 (mult:DI (match_operand:DI 1 "arith_operand" "")
3967 (match_operand:DI 2 "arith_operand" "")))]
3968 "TARGET_ARCH64 || TARGET_V8PLUS"
3972 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
3977 (define_insn "*muldi3_sp64"
3978 [(set (match_operand:DI 0 "register_operand" "=r")
3979 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
3980 (match_operand:DI 2 "arith_operand" "rI")))]
3983 [(set_attr "type" "imul")])
3985 ;; V8plus wide multiply.
3987 (define_insn "muldi3_v8plus"
3988 [(set (match_operand:DI 0 "register_operand" "=r,h")
3989 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
3990 (match_operand:DI 2 "arith_operand" "rI,rI")))
3991 (clobber (match_scratch:SI 3 "=&h,X"))
3992 (clobber (match_scratch:SI 4 "=&h,X"))]
3995 if (sparc_check_64 (operands[1], insn) <= 0)
3996 output_asm_insn ("srl\t%L1, 0, %L1", operands);
3997 if (which_alternative == 1)
3998 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
3999 if (GET_CODE (operands[2]) == CONST_INT)
4001 if (which_alternative == 1)
4002 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
4004 return "sllx\t%H1, 32, %3\n\tor\t%L1, %3, %3\n\tmulx\t%3, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0";
4006 else if (rtx_equal_p (operands[1], operands[2]))
4008 if (which_alternative == 1)
4009 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
4011 return "sllx\t%H1, 32, %3\n\tor\t%L1, %3, %3\n\tmulx\t%3, %3, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0";
4013 if (sparc_check_64 (operands[2], insn) <= 0)
4014 output_asm_insn ("srl\t%L2, 0, %L2", operands);
4015 if (which_alternative == 1)
4016 return "or\t%L1, %H1, %H1\n\tsllx\t%H2, 32, %L1\n\tor\t%L2, %L1, %L1\n\tmulx\t%H1, %L1, %L0\;srlx\t%L0, 32, %H0";
4018 return "sllx\t%H1, 32, %3\n\tsllx\t%H2, 32, %4\n\tor\t%L1, %3, %3\n\tor\t%L2, %4, %4\n\tmulx\t%3, %4, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0";
4020 [(set_attr "type" "multi")
4021 (set_attr "length" "9,8")])
4023 (define_insn "*cmp_mul_set"
4024 [(set (reg:CC CC_REG)
4025 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4026 (match_operand:SI 2 "arith_operand" "rI"))
4028 (set (match_operand:SI 0 "register_operand" "=r")
4029 (mult:SI (match_dup 1) (match_dup 2)))]
4030 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4031 "smulcc\t%1, %2, %0"
4032 [(set_attr "type" "imul")])
4034 (define_expand "mulsidi3"
4035 [(set (match_operand:DI 0 "register_operand" "")
4036 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4037 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4040 if (CONSTANT_P (operands[2]))
4043 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4045 else if (TARGET_ARCH32)
4046 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4049 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4055 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4060 ;; V9 puts the 64-bit product in a 64-bit register. Only out or global
4061 ;; registers can hold 64-bit values in the V8plus environment.
4063 (define_insn "mulsidi3_v8plus"
4064 [(set (match_operand:DI 0 "register_operand" "=h,r")
4065 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4066 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4067 (clobber (match_scratch:SI 3 "=X,&h"))]
4070 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4071 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4072 [(set_attr "type" "multi")
4073 (set_attr "length" "2,3")])
4076 (define_insn "const_mulsidi3_v8plus"
4077 [(set (match_operand:DI 0 "register_operand" "=h,r")
4078 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4079 (match_operand:DI 2 "small_int_operand" "I,I")))
4080 (clobber (match_scratch:SI 3 "=X,&h"))]
4083 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4084 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4085 [(set_attr "type" "multi")
4086 (set_attr "length" "2,3")])
4089 (define_insn "*mulsidi3_sp32"
4090 [(set (match_operand:DI 0 "register_operand" "=r")
4091 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4092 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4095 return TARGET_SPARCLET
4096 ? "smuld\t%1, %2, %L0"
4097 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4100 (if_then_else (eq_attr "isa" "sparclet")
4101 (const_string "imul") (const_string "multi")))
4102 (set (attr "length")
4103 (if_then_else (eq_attr "isa" "sparclet")
4104 (const_int 1) (const_int 2)))])
4106 (define_insn "*mulsidi3_sp64"
4107 [(set (match_operand:DI 0 "register_operand" "=r")
4108 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4109 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4110 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4112 [(set_attr "type" "imul")])
4114 ;; Extra pattern, because sign_extend of a constant isn't valid.
4117 (define_insn "const_mulsidi3_sp32"
4118 [(set (match_operand:DI 0 "register_operand" "=r")
4119 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4120 (match_operand:DI 2 "small_int_operand" "I")))]
4123 return TARGET_SPARCLET
4124 ? "smuld\t%1, %2, %L0"
4125 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4128 (if_then_else (eq_attr "isa" "sparclet")
4129 (const_string "imul") (const_string "multi")))
4130 (set (attr "length")
4131 (if_then_else (eq_attr "isa" "sparclet")
4132 (const_int 1) (const_int 2)))])
4134 (define_insn "const_mulsidi3_sp64"
4135 [(set (match_operand:DI 0 "register_operand" "=r")
4136 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4137 (match_operand:DI 2 "small_int_operand" "I")))]
4138 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4140 [(set_attr "type" "imul")])
4142 (define_expand "smulsi3_highpart"
4143 [(set (match_operand:SI 0 "register_operand" "")
4145 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4146 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4148 "TARGET_HARD_MUL && TARGET_ARCH32"
4150 if (CONSTANT_P (operands[2]))
4154 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4160 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4165 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4166 operands[2], GEN_INT (32)));
4172 (define_insn "smulsi3_highpart_v8plus"
4173 [(set (match_operand:SI 0 "register_operand" "=h,r")
4175 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4176 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4177 (match_operand:SI 3 "small_int_operand" "I,I"))))
4178 (clobber (match_scratch:SI 4 "=X,&h"))]
4181 smul\t%1, %2, %0\;srlx\t%0, %3, %0
4182 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4183 [(set_attr "type" "multi")
4184 (set_attr "length" "2")])
4186 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4189 [(set (match_operand:SI 0 "register_operand" "=h,r")
4192 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4193 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4194 (match_operand:SI 3 "small_int_operand" "I,I"))
4196 (clobber (match_scratch:SI 4 "=X,&h"))]
4199 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4200 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4201 [(set_attr "type" "multi")
4202 (set_attr "length" "2")])
4205 (define_insn "const_smulsi3_highpart_v8plus"
4206 [(set (match_operand:SI 0 "register_operand" "=h,r")
4208 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4209 (match_operand:DI 2 "small_int_operand" "I,I"))
4210 (match_operand:SI 3 "small_int_operand" "I,I"))))
4211 (clobber (match_scratch:SI 4 "=X,&h"))]
4214 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4215 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4216 [(set_attr "type" "multi")
4217 (set_attr "length" "2")])
4220 (define_insn "*smulsi3_highpart_sp32"
4221 [(set (match_operand:SI 0 "register_operand" "=r")
4223 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4224 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4227 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4228 [(set_attr "type" "multi")
4229 (set_attr "length" "2")])
4232 (define_insn "const_smulsi3_highpart"
4233 [(set (match_operand:SI 0 "register_operand" "=r")
4235 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4236 (match_operand:DI 2 "small_int_operand" "i"))
4239 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4240 [(set_attr "type" "multi")
4241 (set_attr "length" "2")])
4243 (define_expand "umulsidi3"
4244 [(set (match_operand:DI 0 "register_operand" "")
4245 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4246 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4249 if (CONSTANT_P (operands[2]))
4252 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4254 else if (TARGET_ARCH32)
4255 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4258 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4264 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4270 (define_insn "umulsidi3_v8plus"
4271 [(set (match_operand:DI 0 "register_operand" "=h,r")
4272 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4273 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4274 (clobber (match_scratch:SI 3 "=X,&h"))]
4277 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4278 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4279 [(set_attr "type" "multi")
4280 (set_attr "length" "2,3")])
4283 (define_insn "*umulsidi3_sp32"
4284 [(set (match_operand:DI 0 "register_operand" "=r")
4285 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4286 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4289 return TARGET_SPARCLET
4290 ? "umuld\t%1, %2, %L0"
4291 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4294 (if_then_else (eq_attr "isa" "sparclet")
4295 (const_string "imul") (const_string "multi")))
4296 (set (attr "length")
4297 (if_then_else (eq_attr "isa" "sparclet")
4298 (const_int 1) (const_int 2)))])
4300 (define_insn "*umulsidi3_sp64"
4301 [(set (match_operand:DI 0 "register_operand" "=r")
4302 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4303 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4304 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4306 [(set_attr "type" "imul")])
4308 ;; Extra pattern, because sign_extend of a constant isn't valid.
4311 (define_insn "const_umulsidi3_sp32"
4312 [(set (match_operand:DI 0 "register_operand" "=r")
4313 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4314 (match_operand:DI 2 "uns_small_int_operand" "")))]
4317 return TARGET_SPARCLET
4318 ? "umuld\t%1, %s2, %L0"
4319 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4322 (if_then_else (eq_attr "isa" "sparclet")
4323 (const_string "imul") (const_string "multi")))
4324 (set (attr "length")
4325 (if_then_else (eq_attr "isa" "sparclet")
4326 (const_int 1) (const_int 2)))])
4328 (define_insn "const_umulsidi3_sp64"
4329 [(set (match_operand:DI 0 "register_operand" "=r")
4330 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4331 (match_operand:DI 2 "uns_small_int_operand" "")))]
4332 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4334 [(set_attr "type" "imul")])
4337 (define_insn "const_umulsidi3_v8plus"
4338 [(set (match_operand:DI 0 "register_operand" "=h,r")
4339 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4340 (match_operand:DI 2 "uns_small_int_operand" "")))
4341 (clobber (match_scratch:SI 3 "=X,h"))]
4344 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4345 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4346 [(set_attr "type" "multi")
4347 (set_attr "length" "2,3")])
4349 (define_expand "umulsi3_highpart"
4350 [(set (match_operand:SI 0 "register_operand" "")
4352 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4353 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4355 "TARGET_HARD_MUL && TARGET_ARCH32"
4357 if (CONSTANT_P (operands[2]))
4361 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4367 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4372 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4373 operands[2], GEN_INT (32)));
4379 (define_insn "umulsi3_highpart_v8plus"
4380 [(set (match_operand:SI 0 "register_operand" "=h,r")
4382 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4383 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4384 (match_operand:SI 3 "small_int_operand" "I,I"))))
4385 (clobber (match_scratch:SI 4 "=X,h"))]
4388 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4389 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4390 [(set_attr "type" "multi")
4391 (set_attr "length" "2")])
4394 (define_insn "const_umulsi3_highpart_v8plus"
4395 [(set (match_operand:SI 0 "register_operand" "=h,r")
4397 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4398 (match_operand:DI 2 "uns_small_int_operand" ""))
4399 (match_operand:SI 3 "small_int_operand" "I,I"))))
4400 (clobber (match_scratch:SI 4 "=X,h"))]
4403 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4404 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4405 [(set_attr "type" "multi")
4406 (set_attr "length" "2")])
4409 (define_insn "*umulsi3_highpart_sp32"
4410 [(set (match_operand:SI 0 "register_operand" "=r")
4412 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4413 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4416 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4417 [(set_attr "type" "multi")
4418 (set_attr "length" "2")])
4421 (define_insn "const_umulsi3_highpart"
4422 [(set (match_operand:SI 0 "register_operand" "=r")
4424 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4425 (match_operand:DI 2 "uns_small_int_operand" ""))
4428 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4429 [(set_attr "type" "multi")
4430 (set_attr "length" "2")])
4432 (define_expand "divsi3"
4433 [(parallel [(set (match_operand:SI 0 "register_operand" "")
4434 (div:SI (match_operand:SI 1 "register_operand" "")
4435 (match_operand:SI 2 "input_operand" "")))
4436 (clobber (match_scratch:SI 3 ""))])]
4437 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4441 operands[3] = gen_reg_rtx(SImode);
4442 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4443 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4449 ;; The V8 architecture specifies that there must be at least 3 instructions
4450 ;; between a write to the Y register and a use of it for correct results.
4451 ;; We try to fill one of them with a simple constant or a memory load.
4453 (define_insn "divsi3_sp32"
4454 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4455 (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4456 (match_operand:SI 2 "input_operand" "rI,K,m")))
4457 (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4458 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4460 output_asm_insn ("sra\t%1, 31, %3", operands);
4461 output_asm_insn ("wr\t%3, 0, %%y", operands);
4463 switch (which_alternative)
4467 return "sdiv\t%1, %2, %0";
4469 return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4472 return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4474 return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4477 return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4479 return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4484 [(set_attr "type" "multi")
4485 (set (attr "length")
4486 (if_then_else (eq_attr "isa" "v9")
4487 (const_int 4) (const_int 6)))])
4489 (define_insn "divsi3_sp64"
4490 [(set (match_operand:SI 0 "register_operand" "=r")
4491 (div:SI (match_operand:SI 1 "register_operand" "r")
4492 (match_operand:SI 2 "input_operand" "rI")))
4493 (use (match_operand:SI 3 "register_operand" "r"))]
4494 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4495 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4496 [(set_attr "type" "multi")
4497 (set_attr "length" "2")])
4499 (define_insn "divdi3"
4500 [(set (match_operand:DI 0 "register_operand" "=r")
4501 (div:DI (match_operand:DI 1 "register_operand" "r")
4502 (match_operand:DI 2 "arith_operand" "rI")))]
4505 [(set_attr "type" "idiv")])
4507 (define_insn "*cmp_sdiv_cc_set"
4508 [(set (reg:CC CC_REG)
4509 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4510 (match_operand:SI 2 "arith_operand" "rI"))
4512 (set (match_operand:SI 0 "register_operand" "=r")
4513 (div:SI (match_dup 1) (match_dup 2)))
4514 (clobber (match_scratch:SI 3 "=&r"))]
4515 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4517 output_asm_insn ("sra\t%1, 31, %3", operands);
4518 output_asm_insn ("wr\t%3, 0, %%y", operands);
4521 return "sdivcc\t%1, %2, %0";
4523 return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4525 [(set_attr "type" "multi")
4526 (set (attr "length")
4527 (if_then_else (eq_attr "isa" "v9")
4528 (const_int 3) (const_int 6)))])
4531 (define_expand "udivsi3"
4532 [(set (match_operand:SI 0 "register_operand" "")
4533 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4534 (match_operand:SI 2 "input_operand" "")))]
4535 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4538 ;; The V8 architecture specifies that there must be at least 3 instructions
4539 ;; between a write to the Y register and a use of it for correct results.
4540 ;; We try to fill one of them with a simple constant or a memory load.
4542 (define_insn "udivsi3_sp32"
4543 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
4544 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
4545 (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
4546 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4548 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4550 switch (which_alternative)
4554 return "udiv\t%1, %2, %0";
4556 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
4559 return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
4561 return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4564 return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
4566 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4569 return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
4571 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
4576 [(set_attr "type" "multi")
4577 (set (attr "length")
4578 (if_then_else (eq_attr "isa" "v9")
4579 (const_int 3) (const_int 5)))])
4581 (define_insn "udivsi3_sp64"
4582 [(set (match_operand:SI 0 "register_operand" "=r")
4583 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
4584 (match_operand:SI 2 "input_operand" "rI")))]
4585 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4586 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
4587 [(set_attr "type" "multi")
4588 (set_attr "length" "2")])
4590 (define_insn "udivdi3"
4591 [(set (match_operand:DI 0 "register_operand" "=r")
4592 (udiv:DI (match_operand:DI 1 "register_operand" "r")
4593 (match_operand:DI 2 "arith_operand" "rI")))]
4596 [(set_attr "type" "idiv")])
4598 (define_insn "*cmp_udiv_cc_set"
4599 [(set (reg:CC CC_REG)
4600 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
4601 (match_operand:SI 2 "arith_operand" "rI"))
4603 (set (match_operand:SI 0 "register_operand" "=r")
4604 (udiv:SI (match_dup 1) (match_dup 2)))]
4605 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4607 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4610 return "udivcc\t%1, %2, %0";
4612 return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
4614 [(set_attr "type" "multi")
4615 (set (attr "length")
4616 (if_then_else (eq_attr "isa" "v9")
4617 (const_int 2) (const_int 5)))])
4619 ; sparclet multiply/accumulate insns
4621 (define_insn "*smacsi"
4622 [(set (match_operand:SI 0 "register_operand" "=r")
4623 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
4624 (match_operand:SI 2 "arith_operand" "rI"))
4625 (match_operand:SI 3 "register_operand" "0")))]
4628 [(set_attr "type" "imul")])
4630 (define_insn "*smacdi"
4631 [(set (match_operand:DI 0 "register_operand" "=r")
4632 (plus:DI (mult:DI (sign_extend:DI
4633 (match_operand:SI 1 "register_operand" "%r"))
4635 (match_operand:SI 2 "register_operand" "r")))
4636 (match_operand:DI 3 "register_operand" "0")))]
4638 "smacd\t%1, %2, %L0"
4639 [(set_attr "type" "imul")])
4641 (define_insn "*umacdi"
4642 [(set (match_operand:DI 0 "register_operand" "=r")
4643 (plus:DI (mult:DI (zero_extend:DI
4644 (match_operand:SI 1 "register_operand" "%r"))
4646 (match_operand:SI 2 "register_operand" "r")))
4647 (match_operand:DI 3 "register_operand" "0")))]
4649 "umacd\t%1, %2, %L0"
4650 [(set_attr "type" "imul")])
4653 ;; Boolean instructions.
4655 ;; We define DImode `and' so with DImode `not' we can get
4656 ;; DImode `andn'. Other combinations are possible.
4658 (define_expand "and<V64I:mode>3"
4659 [(set (match_operand:V64I 0 "register_operand" "")
4660 (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
4661 (match_operand:V64I 2 "arith_double_operand" "")))]
4665 (define_insn "*and<V64I:mode>3_sp32"
4666 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4667 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4668 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4673 [(set_attr "type" "*,fga")
4674 (set_attr "length" "2,*")
4675 (set_attr "fptype" "*,double")])
4677 (define_insn "*and<V64I:mode>3_sp64"
4678 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4679 (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4680 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4685 [(set_attr "type" "*,fga")
4686 (set_attr "fptype" "*,double")])
4688 (define_insn "and<V32I:mode>3"
4689 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4690 (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4691 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4696 [(set_attr "type" "*,fga")
4697 (set_attr "fptype" "*,single")])
4700 [(set (match_operand:SI 0 "register_operand" "")
4701 (and:SI (match_operand:SI 1 "register_operand" "")
4702 (match_operand:SI 2 "const_compl_high_operand" "")))
4703 (clobber (match_operand:SI 3 "register_operand" ""))]
4705 [(set (match_dup 3) (match_dup 4))
4706 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
4708 operands[4] = GEN_INT (~INTVAL (operands[2]));
4711 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
4712 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4713 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4714 (match_operand:V64I 2 "register_operand" "r,b")))]
4718 fandnot1\t%1, %2, %0"
4719 "&& reload_completed
4720 && ((GET_CODE (operands[0]) == REG
4721 && REGNO (operands[0]) < 32)
4722 || (GET_CODE (operands[0]) == SUBREG
4723 && GET_CODE (SUBREG_REG (operands[0])) == REG
4724 && REGNO (SUBREG_REG (operands[0])) < 32))"
4725 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
4726 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
4727 "operands[3] = gen_highpart (SImode, operands[0]);
4728 operands[4] = gen_highpart (SImode, operands[1]);
4729 operands[5] = gen_highpart (SImode, operands[2]);
4730 operands[6] = gen_lowpart (SImode, operands[0]);
4731 operands[7] = gen_lowpart (SImode, operands[1]);
4732 operands[8] = gen_lowpart (SImode, operands[2]);"
4733 [(set_attr "type" "*,fga")
4734 (set_attr "length" "2,*")
4735 (set_attr "fptype" "*,double")])
4737 (define_insn "*and_not_<V64I:mode>_sp64"
4738 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4739 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4740 (match_operand:V64I 2 "register_operand" "r,b")))]
4744 fandnot1\t%1, %2, %0"
4745 [(set_attr "type" "*,fga")
4746 (set_attr "fptype" "*,double")])
4748 (define_insn "*and_not_<V32I:mode>"
4749 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4750 (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
4751 (match_operand:V32I 2 "register_operand" "r,d")))]
4755 fandnot1s\t%1, %2, %0"
4756 [(set_attr "type" "*,fga")
4757 (set_attr "fptype" "*,single")])
4759 (define_expand "ior<V64I:mode>3"
4760 [(set (match_operand:V64I 0 "register_operand" "")
4761 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
4762 (match_operand:V64I 2 "arith_double_operand" "")))]
4766 (define_insn "*ior<V64I:mode>3_sp32"
4767 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4768 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4769 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4774 [(set_attr "type" "*,fga")
4775 (set_attr "length" "2,*")
4776 (set_attr "fptype" "*,double")])
4778 (define_insn "*ior<V64I:mode>3_sp64"
4779 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4780 (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4781 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4786 [(set_attr "type" "*,fga")
4787 (set_attr "fptype" "*,double")])
4789 (define_insn "ior<V32I:mode>3"
4790 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4791 (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4792 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4797 [(set_attr "type" "*,fga")
4798 (set_attr "fptype" "*,single")])
4801 [(set (match_operand:SI 0 "register_operand" "")
4802 (ior:SI (match_operand:SI 1 "register_operand" "")
4803 (match_operand:SI 2 "const_compl_high_operand" "")))
4804 (clobber (match_operand:SI 3 "register_operand" ""))]
4806 [(set (match_dup 3) (match_dup 4))
4807 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4809 operands[4] = GEN_INT (~INTVAL (operands[2]));
4812 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
4813 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4814 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4815 (match_operand:V64I 2 "register_operand" "r,b")))]
4819 fornot1\t%1, %2, %0"
4820 "&& reload_completed
4821 && ((GET_CODE (operands[0]) == REG
4822 && REGNO (operands[0]) < 32)
4823 || (GET_CODE (operands[0]) == SUBREG
4824 && GET_CODE (SUBREG_REG (operands[0])) == REG
4825 && REGNO (SUBREG_REG (operands[0])) < 32))"
4826 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
4827 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
4828 "operands[3] = gen_highpart (SImode, operands[0]);
4829 operands[4] = gen_highpart (SImode, operands[1]);
4830 operands[5] = gen_highpart (SImode, operands[2]);
4831 operands[6] = gen_lowpart (SImode, operands[0]);
4832 operands[7] = gen_lowpart (SImode, operands[1]);
4833 operands[8] = gen_lowpart (SImode, operands[2]);"
4834 [(set_attr "type" "*,fga")
4835 (set_attr "length" "2,*")
4836 (set_attr "fptype" "*,double")])
4838 (define_insn "*or_not_<V64I:mode>_sp64"
4839 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4840 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4841 (match_operand:V64I 2 "register_operand" "r,b")))]
4845 fornot1\t%1, %2, %0"
4846 [(set_attr "type" "*,fga")
4847 (set_attr "fptype" "*,double")])
4849 (define_insn "*or_not_<V32I:mode>"
4850 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4851 (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
4852 (match_operand:V32I 2 "register_operand" "r,d")))]
4856 fornot1s\t%1, %2, %0"
4857 [(set_attr "type" "*,fga")
4858 (set_attr "fptype" "*,single")])
4860 (define_expand "xor<V64I:mode>3"
4861 [(set (match_operand:V64I 0 "register_operand" "")
4862 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
4863 (match_operand:V64I 2 "arith_double_operand" "")))]
4867 (define_insn "*xor<V64I:mode>3_sp32"
4868 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4869 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4870 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4875 [(set_attr "type" "*,fga")
4876 (set_attr "length" "2,*")
4877 (set_attr "fptype" "*,double")])
4879 (define_insn "*xor<V64I:mode>3_sp64"
4880 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4881 (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
4882 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4887 [(set_attr "type" "*,fga")
4888 (set_attr "fptype" "*,double")])
4890 (define_insn "xor<V32I:mode>3"
4891 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4892 (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
4893 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4898 [(set_attr "type" "*,fga")
4899 (set_attr "fptype" "*,single")])
4902 [(set (match_operand:SI 0 "register_operand" "")
4903 (xor:SI (match_operand:SI 1 "register_operand" "")
4904 (match_operand:SI 2 "const_compl_high_operand" "")))
4905 (clobber (match_operand:SI 3 "register_operand" ""))]
4907 [(set (match_dup 3) (match_dup 4))
4908 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4910 operands[4] = GEN_INT (~INTVAL (operands[2]));
4914 [(set (match_operand:SI 0 "register_operand" "")
4915 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
4916 (match_operand:SI 2 "const_compl_high_operand" ""))))
4917 (clobber (match_operand:SI 3 "register_operand" ""))]
4919 [(set (match_dup 3) (match_dup 4))
4920 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
4922 operands[4] = GEN_INT (~INTVAL (operands[2]));
4925 ;; Split DImode logical operations requiring two instructions.
4927 [(set (match_operand:V64I 0 "register_operand" "")
4928 (match_operator:V64I 1 "cc_arith_operator" ; AND, IOR, XOR
4929 [(match_operand:V64I 2 "register_operand" "")
4930 (match_operand:V64I 3 "arith_double_operand" "")]))]
4933 && ((GET_CODE (operands[0]) == REG
4934 && REGNO (operands[0]) < 32)
4935 || (GET_CODE (operands[0]) == SUBREG
4936 && GET_CODE (SUBREG_REG (operands[0])) == REG
4937 && REGNO (SUBREG_REG (operands[0])) < 32))"
4938 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
4939 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
4941 operands[4] = gen_highpart (SImode, operands[0]);
4942 operands[5] = gen_lowpart (SImode, operands[0]);
4943 operands[6] = gen_highpart (SImode, operands[2]);
4944 operands[7] = gen_lowpart (SImode, operands[2]);
4945 #if HOST_BITS_PER_WIDE_INT == 32
4946 if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
4948 if (INTVAL (operands[3]) < 0)
4949 operands[8] = constm1_rtx;
4951 operands[8] = const0_rtx;
4955 operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
4956 operands[9] = gen_lowpart (SImode, operands[3]);
4959 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
4960 ;; Combine now canonicalizes to the rightmost expression.
4961 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
4962 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4963 (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
4964 (match_operand:V64I 2 "register_operand" "r,b"))))]
4969 "&& reload_completed
4970 && ((GET_CODE (operands[0]) == REG
4971 && REGNO (operands[0]) < 32)
4972 || (GET_CODE (operands[0]) == SUBREG
4973 && GET_CODE (SUBREG_REG (operands[0])) == REG
4974 && REGNO (SUBREG_REG (operands[0])) < 32))"
4975 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
4976 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
4977 "operands[3] = gen_highpart (SImode, operands[0]);
4978 operands[4] = gen_highpart (SImode, operands[1]);
4979 operands[5] = gen_highpart (SImode, operands[2]);
4980 operands[6] = gen_lowpart (SImode, operands[0]);
4981 operands[7] = gen_lowpart (SImode, operands[1]);
4982 operands[8] = gen_lowpart (SImode, operands[2]);"
4983 [(set_attr "type" "*,fga")
4984 (set_attr "length" "2,*")
4985 (set_attr "fptype" "*,double")])
4987 (define_insn "*xor_not_<V64I:mode>_sp64"
4988 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4989 (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
4990 (match_operand:V64I 2 "arith_operand" "rI,b"))))]
4995 [(set_attr "type" "*,fga")
4996 (set_attr "fptype" "*,double")])
4998 (define_insn "*xor_not_<V32I:mode>"
4999 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5000 (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
5001 (match_operand:V32I 2 "arith_operand" "rI,d"))))]
5006 [(set_attr "type" "*,fga")
5007 (set_attr "fptype" "*,single")])
5009 ;; These correspond to the above in the case where we also (or only)
5010 ;; want to set the condition code.
5012 (define_insn "*cmp_cc_arith_op"
5013 [(set (reg:CC CC_REG)
5015 (match_operator:SI 2 "cc_arith_operator"
5016 [(match_operand:SI 0 "arith_operand" "%r")
5017 (match_operand:SI 1 "arith_operand" "rI")])
5020 "%A2cc\t%0, %1, %%g0"
5021 [(set_attr "type" "compare")])
5023 (define_insn "*cmp_ccx_arith_op"
5024 [(set (reg:CCX CC_REG)
5026 (match_operator:DI 2 "cc_arith_operator"
5027 [(match_operand:DI 0 "arith_operand" "%r")
5028 (match_operand:DI 1 "arith_operand" "rI")])
5031 "%A2cc\t%0, %1, %%g0"
5032 [(set_attr "type" "compare")])
5034 (define_insn "*cmp_cc_arith_op_set"
5035 [(set (reg:CC CC_REG)
5037 (match_operator:SI 3 "cc_arith_operator"
5038 [(match_operand:SI 1 "arith_operand" "%r")
5039 (match_operand:SI 2 "arith_operand" "rI")])
5041 (set (match_operand:SI 0 "register_operand" "=r")
5042 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5043 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5045 [(set_attr "type" "compare")])
5047 (define_insn "*cmp_ccx_arith_op_set"
5048 [(set (reg:CCX CC_REG)
5050 (match_operator:DI 3 "cc_arith_operator"
5051 [(match_operand:DI 1 "arith_operand" "%r")
5052 (match_operand:DI 2 "arith_operand" "rI")])
5054 (set (match_operand:DI 0 "register_operand" "=r")
5055 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5056 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5058 [(set_attr "type" "compare")])
5060 (define_insn "*cmp_cc_xor_not"
5061 [(set (reg:CC CC_REG)
5063 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5064 (match_operand:SI 1 "arith_operand" "rI")))
5067 "xnorcc\t%r0, %1, %%g0"
5068 [(set_attr "type" "compare")])
5070 (define_insn "*cmp_ccx_xor_not"
5071 [(set (reg:CCX CC_REG)
5073 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5074 (match_operand:DI 1 "arith_operand" "rI")))
5077 "xnorcc\t%r0, %1, %%g0"
5078 [(set_attr "type" "compare")])
5080 (define_insn "*cmp_cc_xor_not_set"
5081 [(set (reg:CC CC_REG)
5083 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5084 (match_operand:SI 2 "arith_operand" "rI")))
5086 (set (match_operand:SI 0 "register_operand" "=r")
5087 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5089 "xnorcc\t%r1, %2, %0"
5090 [(set_attr "type" "compare")])
5092 (define_insn "*cmp_ccx_xor_not_set"
5093 [(set (reg:CCX CC_REG)
5095 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5096 (match_operand:DI 2 "arith_operand" "rI")))
5098 (set (match_operand:DI 0 "register_operand" "=r")
5099 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5101 "xnorcc\t%r1, %2, %0"
5102 [(set_attr "type" "compare")])
5104 (define_insn "*cmp_cc_arith_op_not"
5105 [(set (reg:CC CC_REG)
5107 (match_operator:SI 2 "cc_arith_not_operator"
5108 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5109 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5112 "%B2cc\t%r1, %0, %%g0"
5113 [(set_attr "type" "compare")])
5115 (define_insn "*cmp_ccx_arith_op_not"
5116 [(set (reg:CCX CC_REG)
5118 (match_operator:DI 2 "cc_arith_not_operator"
5119 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5120 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5123 "%B2cc\t%r1, %0, %%g0"
5124 [(set_attr "type" "compare")])
5126 (define_insn "*cmp_cc_arith_op_not_set"
5127 [(set (reg:CC CC_REG)
5129 (match_operator:SI 3 "cc_arith_not_operator"
5130 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5131 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5133 (set (match_operand:SI 0 "register_operand" "=r")
5134 (match_operator:SI 4 "cc_arith_not_operator"
5135 [(not:SI (match_dup 1)) (match_dup 2)]))]
5136 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5137 "%B3cc\t%r2, %1, %0"
5138 [(set_attr "type" "compare")])
5140 (define_insn "*cmp_ccx_arith_op_not_set"
5141 [(set (reg:CCX CC_REG)
5143 (match_operator:DI 3 "cc_arith_not_operator"
5144 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5145 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5147 (set (match_operand:DI 0 "register_operand" "=r")
5148 (match_operator:DI 4 "cc_arith_not_operator"
5149 [(not:DI (match_dup 1)) (match_dup 2)]))]
5150 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5151 "%B3cc\t%r2, %1, %0"
5152 [(set_attr "type" "compare")])
5154 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5155 ;; does not know how to make it work for constants.
5157 (define_expand "negdi2"
5158 [(set (match_operand:DI 0 "register_operand" "=r")
5159 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5162 if (! TARGET_ARCH64)
5164 emit_insn (gen_rtx_PARALLEL
5167 gen_rtx_SET (VOIDmode, operand0,
5168 gen_rtx_NEG (DImode, operand1)),
5169 gen_rtx_CLOBBER (VOIDmode,
5170 gen_rtx_REG (CCmode,
5176 (define_insn_and_split "*negdi2_sp32"
5177 [(set (match_operand:DI 0 "register_operand" "=r")
5178 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5179 (clobber (reg:CC CC_REG))]
5182 "&& reload_completed"
5183 [(parallel [(set (reg:CC_NOOV CC_REG)
5184 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5186 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5187 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5188 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
5189 "operands[2] = gen_highpart (SImode, operands[0]);
5190 operands[3] = gen_highpart (SImode, operands[1]);
5191 operands[4] = gen_lowpart (SImode, operands[0]);
5192 operands[5] = gen_lowpart (SImode, operands[1]);"
5193 [(set_attr "length" "2")])
5195 (define_insn "*negdi2_sp64"
5196 [(set (match_operand:DI 0 "register_operand" "=r")
5197 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5199 "sub\t%%g0, %1, %0")
5201 (define_insn "negsi2"
5202 [(set (match_operand:SI 0 "register_operand" "=r")
5203 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5205 "sub\t%%g0, %1, %0")
5207 (define_insn "*cmp_cc_neg"
5208 [(set (reg:CC_NOOV CC_REG)
5209 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5212 "subcc\t%%g0, %0, %%g0"
5213 [(set_attr "type" "compare")])
5215 (define_insn "*cmp_ccx_neg"
5216 [(set (reg:CCX_NOOV CC_REG)
5217 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5220 "subcc\t%%g0, %0, %%g0"
5221 [(set_attr "type" "compare")])
5223 (define_insn "*cmp_cc_set_neg"
5224 [(set (reg:CC_NOOV CC_REG)
5225 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5227 (set (match_operand:SI 0 "register_operand" "=r")
5228 (neg:SI (match_dup 1)))]
5230 "subcc\t%%g0, %1, %0"
5231 [(set_attr "type" "compare")])
5233 (define_insn "*cmp_ccx_set_neg"
5234 [(set (reg:CCX_NOOV CC_REG)
5235 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5237 (set (match_operand:DI 0 "register_operand" "=r")
5238 (neg:DI (match_dup 1)))]
5240 "subcc\t%%g0, %1, %0"
5241 [(set_attr "type" "compare")])
5243 ;; We cannot use the "not" pseudo insn because the Sun assembler
5244 ;; does not know how to make it work for constants.
5245 (define_expand "one_cmpl<V64I:mode>2"
5246 [(set (match_operand:V64I 0 "register_operand" "")
5247 (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5251 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5252 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5253 (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5258 "&& reload_completed
5259 && ((GET_CODE (operands[0]) == REG
5260 && REGNO (operands[0]) < 32)
5261 || (GET_CODE (operands[0]) == SUBREG
5262 && GET_CODE (SUBREG_REG (operands[0])) == REG
5263 && REGNO (SUBREG_REG (operands[0])) < 32))"
5264 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5265 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5266 "operands[2] = gen_highpart (SImode, operands[0]);
5267 operands[3] = gen_highpart (SImode, operands[1]);
5268 operands[4] = gen_lowpart (SImode, operands[0]);
5269 operands[5] = gen_lowpart (SImode, operands[1]);"
5270 [(set_attr "type" "*,fga")
5271 (set_attr "length" "2,*")
5272 (set_attr "fptype" "*,double")])
5274 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5275 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5276 (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5281 [(set_attr "type" "*,fga")
5282 (set_attr "fptype" "*,double")])
5284 (define_insn "one_cmpl<V32I:mode>2"
5285 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5286 (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5291 [(set_attr "type" "*,fga")
5292 (set_attr "fptype" "*,single")])
5294 (define_insn "*cmp_cc_not"
5295 [(set (reg:CC CC_REG)
5296 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5299 "xnorcc\t%%g0, %0, %%g0"
5300 [(set_attr "type" "compare")])
5302 (define_insn "*cmp_ccx_not"
5303 [(set (reg:CCX CC_REG)
5304 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5307 "xnorcc\t%%g0, %0, %%g0"
5308 [(set_attr "type" "compare")])
5310 (define_insn "*cmp_cc_set_not"
5311 [(set (reg:CC CC_REG)
5312 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5314 (set (match_operand:SI 0 "register_operand" "=r")
5315 (not:SI (match_dup 1)))]
5317 "xnorcc\t%%g0, %1, %0"
5318 [(set_attr "type" "compare")])
5320 (define_insn "*cmp_ccx_set_not"
5321 [(set (reg:CCX CC_REG)
5322 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5324 (set (match_operand:DI 0 "register_operand" "=r")
5325 (not:DI (match_dup 1)))]
5327 "xnorcc\t%%g0, %1, %0"
5328 [(set_attr "type" "compare")])
5330 (define_insn "*cmp_cc_set"
5331 [(set (match_operand:SI 0 "register_operand" "=r")
5332 (match_operand:SI 1 "register_operand" "r"))
5333 (set (reg:CC CC_REG)
5334 (compare:CC (match_dup 1)
5338 [(set_attr "type" "compare")])
5340 (define_insn "*cmp_ccx_set64"
5341 [(set (match_operand:DI 0 "register_operand" "=r")
5342 (match_operand:DI 1 "register_operand" "r"))
5343 (set (reg:CCX CC_REG)
5344 (compare:CCX (match_dup 1)
5348 [(set_attr "type" "compare")])
5351 ;; Floating point arithmetic instructions.
5353 (define_expand "addtf3"
5354 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5355 (plus:TF (match_operand:TF 1 "general_operand" "")
5356 (match_operand:TF 2 "general_operand" "")))]
5357 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5358 "emit_tfmode_binop (PLUS, operands); DONE;")
5360 (define_insn "*addtf3_hq"
5361 [(set (match_operand:TF 0 "register_operand" "=e")
5362 (plus:TF (match_operand:TF 1 "register_operand" "e")
5363 (match_operand:TF 2 "register_operand" "e")))]
5364 "TARGET_FPU && TARGET_HARD_QUAD"
5366 [(set_attr "type" "fp")])
5368 (define_insn "adddf3"
5369 [(set (match_operand:DF 0 "register_operand" "=e")
5370 (plus:DF (match_operand:DF 1 "register_operand" "e")
5371 (match_operand:DF 2 "register_operand" "e")))]
5374 [(set_attr "type" "fp")
5375 (set_attr "fptype" "double")])
5377 (define_insn "addsf3"
5378 [(set (match_operand:SF 0 "register_operand" "=f")
5379 (plus:SF (match_operand:SF 1 "register_operand" "f")
5380 (match_operand:SF 2 "register_operand" "f")))]
5383 [(set_attr "type" "fp")])
5385 (define_expand "subtf3"
5386 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5387 (minus:TF (match_operand:TF 1 "general_operand" "")
5388 (match_operand:TF 2 "general_operand" "")))]
5389 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5390 "emit_tfmode_binop (MINUS, operands); DONE;")
5392 (define_insn "*subtf3_hq"
5393 [(set (match_operand:TF 0 "register_operand" "=e")
5394 (minus:TF (match_operand:TF 1 "register_operand" "e")
5395 (match_operand:TF 2 "register_operand" "e")))]
5396 "TARGET_FPU && TARGET_HARD_QUAD"
5398 [(set_attr "type" "fp")])
5400 (define_insn "subdf3"
5401 [(set (match_operand:DF 0 "register_operand" "=e")
5402 (minus:DF (match_operand:DF 1 "register_operand" "e")
5403 (match_operand:DF 2 "register_operand" "e")))]
5406 [(set_attr "type" "fp")
5407 (set_attr "fptype" "double")])
5409 (define_insn "subsf3"
5410 [(set (match_operand:SF 0 "register_operand" "=f")
5411 (minus:SF (match_operand:SF 1 "register_operand" "f")
5412 (match_operand:SF 2 "register_operand" "f")))]
5415 [(set_attr "type" "fp")])
5417 (define_expand "multf3"
5418 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5419 (mult:TF (match_operand:TF 1 "general_operand" "")
5420 (match_operand:TF 2 "general_operand" "")))]
5421 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5422 "emit_tfmode_binop (MULT, operands); DONE;")
5424 (define_insn "*multf3_hq"
5425 [(set (match_operand:TF 0 "register_operand" "=e")
5426 (mult:TF (match_operand:TF 1 "register_operand" "e")
5427 (match_operand:TF 2 "register_operand" "e")))]
5428 "TARGET_FPU && TARGET_HARD_QUAD"
5430 [(set_attr "type" "fpmul")])
5432 (define_insn "muldf3"
5433 [(set (match_operand:DF 0 "register_operand" "=e")
5434 (mult:DF (match_operand:DF 1 "register_operand" "e")
5435 (match_operand:DF 2 "register_operand" "e")))]
5438 [(set_attr "type" "fpmul")
5439 (set_attr "fptype" "double")])
5441 (define_insn "mulsf3"
5442 [(set (match_operand:SF 0 "register_operand" "=f")
5443 (mult:SF (match_operand:SF 1 "register_operand" "f")
5444 (match_operand:SF 2 "register_operand" "f")))]
5447 [(set_attr "type" "fpmul")])
5449 (define_insn "fmadf4"
5450 [(set (match_operand:DF 0 "register_operand" "=e")
5451 (fma:DF (match_operand:DF 1 "register_operand" "e")
5452 (match_operand:DF 2 "register_operand" "e")
5453 (match_operand:DF 3 "register_operand" "e")))]
5455 "fmaddd\t%1, %2, %3, %0"
5456 [(set_attr "type" "fpmul")])
5458 (define_insn "fmsdf4"
5459 [(set (match_operand:DF 0 "register_operand" "=e")
5460 (fma:DF (match_operand:DF 1 "register_operand" "e")
5461 (match_operand:DF 2 "register_operand" "e")
5462 (neg:DF (match_operand:DF 3 "register_operand" "e"))))]
5464 "fmsubd\t%1, %2, %3, %0"
5465 [(set_attr "type" "fpmul")])
5467 (define_insn "*nfmadf4"
5468 [(set (match_operand:DF 0 "register_operand" "=e")
5469 (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5470 (match_operand:DF 2 "register_operand" "e")
5471 (match_operand:DF 3 "register_operand" "e"))))]
5473 "fnmaddd\t%1, %2, %3, %0"
5474 [(set_attr "type" "fpmul")])
5476 (define_insn "*nfmsdf4"
5477 [(set (match_operand:DF 0 "register_operand" "=e")
5478 (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5479 (match_operand:DF 2 "register_operand" "e")
5480 (neg:DF (match_operand:DF 3 "register_operand" "e")))))]
5482 "fnmsubd\t%1, %2, %3, %0"
5483 [(set_attr "type" "fpmul")])
5485 (define_insn "fmasf4"
5486 [(set (match_operand:SF 0 "register_operand" "=f")
5487 (fma:SF (match_operand:SF 1 "register_operand" "f")
5488 (match_operand:SF 2 "register_operand" "f")
5489 (match_operand:SF 3 "register_operand" "f")))]
5491 "fmadds\t%1, %2, %3, %0"
5492 [(set_attr "type" "fpmul")])
5494 (define_insn "fmssf4"
5495 [(set (match_operand:SF 0 "register_operand" "=f")
5496 (fma:SF (match_operand:SF 1 "register_operand" "f")
5497 (match_operand:SF 2 "register_operand" "f")
5498 (neg:SF (match_operand:SF 3 "register_operand" "f"))))]
5500 "fmsubs\t%1, %2, %3, %0"
5501 [(set_attr "type" "fpmul")])
5503 (define_insn "*nfmasf4"
5504 [(set (match_operand:SF 0 "register_operand" "=f")
5505 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5506 (match_operand:SF 2 "register_operand" "f")
5507 (match_operand:SF 3 "register_operand" "f"))))]
5509 "fnmadds\t%1, %2, %3, %0"
5510 [(set_attr "type" "fpmul")])
5512 (define_insn "*nfmssf4"
5513 [(set (match_operand:SF 0 "register_operand" "=f")
5514 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5515 (match_operand:SF 2 "register_operand" "f")
5516 (neg:SF (match_operand:SF 3 "register_operand" "f")))))]
5518 "fnmsubs\t%1, %2, %3, %0"
5519 [(set_attr "type" "fpmul")])
5521 (define_insn "*muldf3_extend"
5522 [(set (match_operand:DF 0 "register_operand" "=e")
5523 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5524 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5525 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
5526 "fsmuld\t%1, %2, %0"
5527 [(set_attr "type" "fpmul")
5528 (set_attr "fptype" "double")])
5530 (define_insn "*multf3_extend"
5531 [(set (match_operand:TF 0 "register_operand" "=e")
5532 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5533 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5534 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5535 "fdmulq\t%1, %2, %0"
5536 [(set_attr "type" "fpmul")])
5538 (define_expand "divtf3"
5539 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5540 (div:TF (match_operand:TF 1 "general_operand" "")
5541 (match_operand:TF 2 "general_operand" "")))]
5542 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5543 "emit_tfmode_binop (DIV, operands); DONE;")
5545 ;; don't have timing for quad-prec. divide.
5546 (define_insn "*divtf3_hq"
5547 [(set (match_operand:TF 0 "register_operand" "=e")
5548 (div:TF (match_operand:TF 1 "register_operand" "e")
5549 (match_operand:TF 2 "register_operand" "e")))]
5550 "TARGET_FPU && TARGET_HARD_QUAD"
5552 [(set_attr "type" "fpdivd")])
5554 (define_insn "divdf3"
5555 [(set (match_operand:DF 0 "register_operand" "=e")
5556 (div:DF (match_operand:DF 1 "register_operand" "e")
5557 (match_operand:DF 2 "register_operand" "e")))]
5560 [(set_attr "type" "fpdivd")
5561 (set_attr "fptype" "double")])
5563 (define_insn "divsf3"
5564 [(set (match_operand:SF 0 "register_operand" "=f")
5565 (div:SF (match_operand:SF 1 "register_operand" "f")
5566 (match_operand:SF 2 "register_operand" "f")))]
5569 [(set_attr "type" "fpdivs")])
5571 (define_expand "negtf2"
5572 [(set (match_operand:TF 0 "register_operand" "=e,e")
5573 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5577 (define_insn_and_split "*negtf2_notv9"
5578 [(set (match_operand:TF 0 "register_operand" "=e,e")
5579 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5580 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5586 "&& reload_completed
5587 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5588 [(set (match_dup 2) (neg:SF (match_dup 3)))
5589 (set (match_dup 4) (match_dup 5))
5590 (set (match_dup 6) (match_dup 7))]
5591 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5592 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5593 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5594 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5595 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5596 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5597 [(set_attr "type" "fpmove,*")
5598 (set_attr "length" "*,2")])
5600 (define_insn_and_split "*negtf2_v9"
5601 [(set (match_operand:TF 0 "register_operand" "=e,e")
5602 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5603 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5604 "TARGET_FPU && TARGET_V9"
5608 "&& reload_completed
5609 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5610 [(set (match_dup 2) (neg:DF (match_dup 3)))
5611 (set (match_dup 4) (match_dup 5))]
5612 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5613 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5614 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5615 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5616 [(set_attr "type" "fpmove,*")
5617 (set_attr "length" "*,2")
5618 (set_attr "fptype" "double")])
5620 (define_expand "negdf2"
5621 [(set (match_operand:DF 0 "register_operand" "")
5622 (neg:DF (match_operand:DF 1 "register_operand" "")))]
5626 (define_insn_and_split "*negdf2_notv9"
5627 [(set (match_operand:DF 0 "register_operand" "=e,e")
5628 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
5629 "TARGET_FPU && ! TARGET_V9"
5633 "&& reload_completed
5634 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5635 [(set (match_dup 2) (neg:SF (match_dup 3)))
5636 (set (match_dup 4) (match_dup 5))]
5637 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5638 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5639 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5640 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5641 [(set_attr "type" "fpmove,*")
5642 (set_attr "length" "*,2")])
5644 (define_insn "*negdf2_v9"
5645 [(set (match_operand:DF 0 "register_operand" "=e")
5646 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5647 "TARGET_FPU && TARGET_V9"
5649 [(set_attr "type" "fpmove")
5650 (set_attr "fptype" "double")])
5652 (define_insn "negsf2"
5653 [(set (match_operand:SF 0 "register_operand" "=f")
5654 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
5657 [(set_attr "type" "fpmove")])
5659 (define_expand "abstf2"
5660 [(set (match_operand:TF 0 "register_operand" "")
5661 (abs:TF (match_operand:TF 1 "register_operand" "")))]
5665 (define_insn_and_split "*abstf2_notv9"
5666 [(set (match_operand:TF 0 "register_operand" "=e,e")
5667 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5668 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5669 "TARGET_FPU && ! TARGET_V9"
5673 "&& reload_completed
5674 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5675 [(set (match_dup 2) (abs:SF (match_dup 3)))
5676 (set (match_dup 4) (match_dup 5))
5677 (set (match_dup 6) (match_dup 7))]
5678 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5679 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5680 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5681 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5682 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5683 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5684 [(set_attr "type" "fpmove,*")
5685 (set_attr "length" "*,2")])
5687 (define_insn "*abstf2_hq_v9"
5688 [(set (match_operand:TF 0 "register_operand" "=e,e")
5689 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5690 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
5694 [(set_attr "type" "fpmove")
5695 (set_attr "fptype" "double,*")])
5697 (define_insn_and_split "*abstf2_v9"
5698 [(set (match_operand:TF 0 "register_operand" "=e,e")
5699 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5700 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
5704 "&& reload_completed
5705 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5706 [(set (match_dup 2) (abs:DF (match_dup 3)))
5707 (set (match_dup 4) (match_dup 5))]
5708 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5709 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5710 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5711 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5712 [(set_attr "type" "fpmove,*")
5713 (set_attr "length" "*,2")
5714 (set_attr "fptype" "double,*")])
5716 (define_expand "absdf2"
5717 [(set (match_operand:DF 0 "register_operand" "")
5718 (abs:DF (match_operand:DF 1 "register_operand" "")))]
5722 (define_insn_and_split "*absdf2_notv9"
5723 [(set (match_operand:DF 0 "register_operand" "=e,e")
5724 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
5725 "TARGET_FPU && ! TARGET_V9"
5729 "&& reload_completed
5730 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5731 [(set (match_dup 2) (abs:SF (match_dup 3)))
5732 (set (match_dup 4) (match_dup 5))]
5733 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5734 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5735 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5736 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5737 [(set_attr "type" "fpmove,*")
5738 (set_attr "length" "*,2")])
5740 (define_insn "*absdf2_v9"
5741 [(set (match_operand:DF 0 "register_operand" "=e")
5742 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5743 "TARGET_FPU && TARGET_V9"
5745 [(set_attr "type" "fpmove")
5746 (set_attr "fptype" "double")])
5748 (define_insn "abssf2"
5749 [(set (match_operand:SF 0 "register_operand" "=f")
5750 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
5753 [(set_attr "type" "fpmove")])
5755 (define_expand "sqrttf2"
5756 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5757 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
5758 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5759 "emit_tfmode_unop (SQRT, operands); DONE;")
5761 (define_insn "*sqrttf2_hq"
5762 [(set (match_operand:TF 0 "register_operand" "=e")
5763 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
5764 "TARGET_FPU && TARGET_HARD_QUAD"
5766 [(set_attr "type" "fpsqrtd")])
5768 (define_insn "sqrtdf2"
5769 [(set (match_operand:DF 0 "register_operand" "=e")
5770 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5773 [(set_attr "type" "fpsqrtd")
5774 (set_attr "fptype" "double")])
5776 (define_insn "sqrtsf2"
5777 [(set (match_operand:SF 0 "register_operand" "=f")
5778 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
5781 [(set_attr "type" "fpsqrts")])
5784 ;; Arithmetic shift instructions.
5786 (define_insn "ashlsi3"
5787 [(set (match_operand:SI 0 "register_operand" "=r")
5788 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5789 (match_operand:SI 2 "arith_operand" "rI")))]
5792 if (GET_CODE (operands[2]) == CONST_INT)
5793 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5794 return "sll\t%1, %2, %0";
5797 (if_then_else (match_operand 2 "const_one_operand" "")
5798 (const_string "ialu") (const_string "shift")))])
5800 (define_expand "ashldi3"
5801 [(set (match_operand:DI 0 "register_operand" "=r")
5802 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5803 (match_operand:SI 2 "arith_operand" "rI")))]
5804 "TARGET_ARCH64 || TARGET_V8PLUS"
5806 if (! TARGET_ARCH64)
5808 if (GET_CODE (operands[2]) == CONST_INT)
5810 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
5815 (define_insn "*ashldi3_sp64"
5816 [(set (match_operand:DI 0 "register_operand" "=r")
5817 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5818 (match_operand:SI 2 "arith_operand" "rI")))]
5821 if (GET_CODE (operands[2]) == CONST_INT)
5822 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5823 return "sllx\t%1, %2, %0";
5826 (if_then_else (match_operand 2 "const_one_operand" "")
5827 (const_string "ialu") (const_string "shift")))])
5830 (define_insn "ashldi3_v8plus"
5831 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5832 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5833 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5834 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5836 "* return output_v8plus_shift (operands, insn, \"sllx\");"
5837 [(set_attr "type" "multi")
5838 (set_attr "length" "5,5,6")])
5840 ;; Optimize (1LL<<x)-1
5841 ;; XXX this also needs to be fixed to handle equal subregs
5842 ;; XXX first before we could re-enable it.
5844 ; [(set (match_operand:DI 0 "register_operand" "=h")
5845 ; (plus:DI (ashift:DI (const_int 1)
5846 ; (match_operand:SI 1 "arith_operand" "rI"))
5848 ; "0 && TARGET_V8PLUS"
5850 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
5851 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5852 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5854 ; [(set_attr "type" "multi")
5855 ; (set_attr "length" "4")])
5857 (define_insn "*cmp_cc_ashift_1"
5858 [(set (reg:CC_NOOV CC_REG)
5859 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
5863 "addcc\t%0, %0, %%g0"
5864 [(set_attr "type" "compare")])
5866 (define_insn "*cmp_cc_set_ashift_1"
5867 [(set (reg:CC_NOOV CC_REG)
5868 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
5871 (set (match_operand:SI 0 "register_operand" "=r")
5872 (ashift:SI (match_dup 1) (const_int 1)))]
5875 [(set_attr "type" "compare")])
5877 (define_insn "ashrsi3"
5878 [(set (match_operand:SI 0 "register_operand" "=r")
5879 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5880 (match_operand:SI 2 "arith_operand" "rI")))]
5883 if (GET_CODE (operands[2]) == CONST_INT)
5884 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5885 return "sra\t%1, %2, %0";
5887 [(set_attr "type" "shift")])
5889 (define_insn "*ashrsi3_extend"
5890 [(set (match_operand:DI 0 "register_operand" "=r")
5891 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5892 (match_operand:SI 2 "arith_operand" "r"))))]
5895 [(set_attr "type" "shift")])
5897 ;; This handles the case as above, but with constant shift instead of
5898 ;; register. Combiner "simplifies" it for us a little bit though.
5899 (define_insn "*ashrsi3_extend2"
5900 [(set (match_operand:DI 0 "register_operand" "=r")
5901 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5903 (match_operand:SI 2 "small_int_operand" "I")))]
5904 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
5906 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5907 return "sra\t%1, %2, %0";
5909 [(set_attr "type" "shift")])
5911 (define_expand "ashrdi3"
5912 [(set (match_operand:DI 0 "register_operand" "=r")
5913 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5914 (match_operand:SI 2 "arith_operand" "rI")))]
5915 "TARGET_ARCH64 || TARGET_V8PLUS"
5917 if (! TARGET_ARCH64)
5919 if (GET_CODE (operands[2]) == CONST_INT)
5920 FAIL; /* prefer generic code in this case */
5921 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
5926 (define_insn "*ashrdi3_sp64"
5927 [(set (match_operand:DI 0 "register_operand" "=r")
5928 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5929 (match_operand:SI 2 "arith_operand" "rI")))]
5933 if (GET_CODE (operands[2]) == CONST_INT)
5934 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5935 return "srax\t%1, %2, %0";
5937 [(set_attr "type" "shift")])
5940 (define_insn "ashrdi3_v8plus"
5941 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5942 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5943 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5944 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5946 "* return output_v8plus_shift (operands, insn, \"srax\");"
5947 [(set_attr "type" "multi")
5948 (set_attr "length" "5,5,6")])
5950 (define_insn "lshrsi3"
5951 [(set (match_operand:SI 0 "register_operand" "=r")
5952 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5953 (match_operand:SI 2 "arith_operand" "rI")))]
5956 if (GET_CODE (operands[2]) == CONST_INT)
5957 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5958 return "srl\t%1, %2, %0";
5960 [(set_attr "type" "shift")])
5962 ;; This handles the case where
5963 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
5964 ;; but combiner "simplifies" it for us.
5965 (define_insn "*lshrsi3_extend"
5966 [(set (match_operand:DI 0 "register_operand" "=r")
5967 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5968 (match_operand:SI 2 "arith_operand" "r")) 0)
5969 (match_operand 3 "const_int_operand" "")))]
5970 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
5972 [(set_attr "type" "shift")])
5974 ;; This handles the case where
5975 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
5976 ;; but combiner "simplifies" it for us.
5977 (define_insn "*lshrsi3_extend2"
5978 [(set (match_operand:DI 0 "register_operand" "=r")
5979 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5980 (match_operand 2 "small_int_operand" "I")
5982 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5984 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
5985 return "srl\t%1, %2, %0";
5987 [(set_attr "type" "shift")])
5989 (define_expand "lshrdi3"
5990 [(set (match_operand:DI 0 "register_operand" "=r")
5991 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5992 (match_operand:SI 2 "arith_operand" "rI")))]
5993 "TARGET_ARCH64 || TARGET_V8PLUS"
5995 if (! TARGET_ARCH64)
5997 if (GET_CODE (operands[2]) == CONST_INT)
5999 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6004 (define_insn "*lshrdi3_sp64"
6005 [(set (match_operand:DI 0 "register_operand" "=r")
6006 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6007 (match_operand:SI 2 "arith_operand" "rI")))]
6010 if (GET_CODE (operands[2]) == CONST_INT)
6011 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6012 return "srlx\t%1, %2, %0";
6014 [(set_attr "type" "shift")])
6017 (define_insn "lshrdi3_v8plus"
6018 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6019 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6020 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6021 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6023 "* return output_v8plus_shift (operands, insn, \"srlx\");"
6024 [(set_attr "type" "multi")
6025 (set_attr "length" "5,5,6")])
6028 [(set (match_operand:SI 0 "register_operand" "=r")
6029 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6031 (match_operand:SI 2 "small_int_operand" "I")))]
6032 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6034 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6035 return "srax\t%1, %2, %0";
6037 [(set_attr "type" "shift")])
6040 [(set (match_operand:SI 0 "register_operand" "=r")
6041 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6043 (match_operand:SI 2 "small_int_operand" "I")))]
6044 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6046 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6047 return "srlx\t%1, %2, %0";
6049 [(set_attr "type" "shift")])
6052 [(set (match_operand:SI 0 "register_operand" "=r")
6053 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6054 (match_operand:SI 2 "small_int_operand" "I")) 4)
6055 (match_operand:SI 3 "small_int_operand" "I")))]
6057 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6058 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6059 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6061 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6063 return "srax\t%1, %2, %0";
6065 [(set_attr "type" "shift")])
6068 [(set (match_operand:SI 0 "register_operand" "=r")
6069 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6070 (match_operand:SI 2 "small_int_operand" "I")) 4)
6071 (match_operand:SI 3 "small_int_operand" "I")))]
6073 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6074 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6075 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6077 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6079 return "srlx\t%1, %2, %0";
6081 [(set_attr "type" "shift")])
6084 ;; Unconditional and other jump instructions.
6087 [(set (pc) (label_ref (match_operand 0 "" "")))]
6089 "* return output_ubranch (operands[0], 0, insn);"
6090 [(set_attr "type" "uncond_branch")])
6092 (define_expand "tablejump"
6093 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6094 (use (label_ref (match_operand 1 "" "")))])]
6097 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6099 /* In pic mode, our address differences are against the base of the
6100 table. Add that base value back in; CSE ought to be able to combine
6101 the two address loads. */
6105 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6107 if (CASE_VECTOR_MODE != Pmode)
6108 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6109 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6110 operands[0] = memory_address (Pmode, tmp);
6114 (define_insn "*tablejump_sp32"
6115 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6116 (use (label_ref (match_operand 1 "" "")))]
6119 [(set_attr "type" "uncond_branch")])
6121 (define_insn "*tablejump_sp64"
6122 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6123 (use (label_ref (match_operand 1 "" "")))]
6126 [(set_attr "type" "uncond_branch")])
6129 ;; Jump to subroutine instructions.
6131 (define_expand "call"
6132 ;; Note that this expression is not used for generating RTL.
6133 ;; All the RTL is generated explicitly below.
6134 [(call (match_operand 0 "call_operand" "")
6135 (match_operand 3 "" "i"))]
6136 ;; operands[2] is next_arg_register
6137 ;; operands[3] is struct_value_size_rtx.
6142 gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
6144 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6146 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6148 /* This is really a PIC sequence. We want to represent
6149 it as a funny jump so its delay slots can be filled.
6151 ??? But if this really *is* a CALL, will not it clobber the
6152 call-clobbered registers? We lose this if it is a JUMP_INSN.
6153 Why cannot we have delay slots filled if it were a CALL? */
6155 /* We accept negative sizes for untyped calls. */
6156 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6161 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6163 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6169 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6170 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6174 fn_rtx = operands[0];
6176 /* We accept negative sizes for untyped calls. */
6177 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6178 sparc_emit_call_insn
6181 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6183 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6186 sparc_emit_call_insn
6189 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6190 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6198 ;; We can't use the same pattern for these two insns, because then registers
6199 ;; in the address may not be properly reloaded.
6201 (define_insn "*call_address_sp32"
6202 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6203 (match_operand 1 "" ""))
6204 (clobber (reg:SI O7_REG))]
6205 ;;- Do not use operand 1 for most machines.
6208 [(set_attr "type" "call")])
6210 (define_insn "*call_symbolic_sp32"
6211 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6212 (match_operand 1 "" ""))
6213 (clobber (reg:SI O7_REG))]
6214 ;;- Do not use operand 1 for most machines.
6217 [(set_attr "type" "call")])
6219 (define_insn "*call_address_sp64"
6220 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6221 (match_operand 1 "" ""))
6222 (clobber (reg:DI O7_REG))]
6223 ;;- Do not use operand 1 for most machines.
6226 [(set_attr "type" "call")])
6228 (define_insn "*call_symbolic_sp64"
6229 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6230 (match_operand 1 "" ""))
6231 (clobber (reg:DI O7_REG))]
6232 ;;- Do not use operand 1 for most machines.
6235 [(set_attr "type" "call")])
6237 ;; This is a call that wants a structure value.
6238 ;; There is no such critter for v9 (??? we may need one anyway).
6239 (define_insn "*call_address_struct_value_sp32"
6240 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6241 (match_operand 1 "" ""))
6242 (match_operand 2 "immediate_operand" "")
6243 (clobber (reg:SI O7_REG))]
6244 ;;- Do not use operand 1 for most machines.
6245 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6247 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6248 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6250 [(set_attr "type" "call_no_delay_slot")
6251 (set_attr "length" "3")])
6253 ;; This is a call that wants a structure value.
6254 ;; There is no such critter for v9 (??? we may need one anyway).
6255 (define_insn "*call_symbolic_struct_value_sp32"
6256 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6257 (match_operand 1 "" ""))
6258 (match_operand 2 "immediate_operand" "")
6259 (clobber (reg:SI O7_REG))]
6260 ;;- Do not use operand 1 for most machines.
6261 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6263 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6264 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6266 [(set_attr "type" "call_no_delay_slot")
6267 (set_attr "length" "3")])
6269 ;; This is a call that may want a structure value. This is used for
6271 (define_insn "*call_address_untyped_struct_value_sp32"
6272 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6273 (match_operand 1 "" ""))
6274 (match_operand 2 "immediate_operand" "")
6275 (clobber (reg:SI O7_REG))]
6276 ;;- Do not use operand 1 for most machines.
6277 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6278 "call\t%a0, %1\n\t nop\n\tnop"
6279 [(set_attr "type" "call_no_delay_slot")
6280 (set_attr "length" "3")])
6282 ;; This is a call that may want a structure value. This is used for
6284 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6285 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6286 (match_operand 1 "" ""))
6287 (match_operand 2 "immediate_operand" "")
6288 (clobber (reg:SI O7_REG))]
6289 ;;- Do not use operand 1 for most machines.
6290 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6291 "call\t%a0, %1\n\t nop\n\tnop"
6292 [(set_attr "type" "call_no_delay_slot")
6293 (set_attr "length" "3")])
6295 (define_expand "call_value"
6296 ;; Note that this expression is not used for generating RTL.
6297 ;; All the RTL is generated explicitly below.
6298 [(set (match_operand 0 "register_operand" "=rf")
6299 (call (match_operand 1 "" "")
6300 (match_operand 4 "" "")))]
6301 ;; operand 2 is stack_size_rtx
6302 ;; operand 3 is next_arg_register
6308 gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6310 fn_rtx = operands[1];
6313 gen_rtx_SET (VOIDmode, operands[0],
6314 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6315 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6317 sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6322 (define_insn "*call_value_address_sp32"
6323 [(set (match_operand 0 "" "=rf")
6324 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6325 (match_operand 2 "" "")))
6326 (clobber (reg:SI O7_REG))]
6327 ;;- Do not use operand 2 for most machines.
6330 [(set_attr "type" "call")])
6332 (define_insn "*call_value_symbolic_sp32"
6333 [(set (match_operand 0 "" "=rf")
6334 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6335 (match_operand 2 "" "")))
6336 (clobber (reg:SI O7_REG))]
6337 ;;- Do not use operand 2 for most machines.
6340 [(set_attr "type" "call")])
6342 (define_insn "*call_value_address_sp64"
6343 [(set (match_operand 0 "" "")
6344 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6345 (match_operand 2 "" "")))
6346 (clobber (reg:DI O7_REG))]
6347 ;;- Do not use operand 2 for most machines.
6350 [(set_attr "type" "call")])
6352 (define_insn "*call_value_symbolic_sp64"
6353 [(set (match_operand 0 "" "")
6354 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6355 (match_operand 2 "" "")))
6356 (clobber (reg:DI O7_REG))]
6357 ;;- Do not use operand 2 for most machines.
6360 [(set_attr "type" "call")])
6362 (define_expand "untyped_call"
6363 [(parallel [(call (match_operand 0 "" "")
6365 (match_operand:BLK 1 "memory_operand" "")
6366 (match_operand 2 "" "")])]
6369 rtx valreg1 = gen_rtx_REG (DImode, 8);
6370 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6371 rtx result = operands[1];
6373 /* Pass constm1 to indicate that it may expect a structure value, but
6374 we don't know what size it is. */
6375 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6377 /* Save the function value registers. */
6378 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6379 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6382 /* The optimizer does not know that the call sets the function value
6383 registers we stored in the result block. We avoid problems by
6384 claiming that all hard registers are used and clobbered at this
6386 emit_insn (gen_blockage ());
6391 ;; Tail call instructions.
6393 (define_expand "sibcall"
6394 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6399 (define_insn "*sibcall_symbolic_sp32"
6400 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6401 (match_operand 1 "" ""))
6404 "* return output_sibcall(insn, operands[0]);"
6405 [(set_attr "type" "sibcall")])
6407 (define_insn "*sibcall_symbolic_sp64"
6408 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6409 (match_operand 1 "" ""))
6412 "* return output_sibcall(insn, operands[0]);"
6413 [(set_attr "type" "sibcall")])
6415 (define_expand "sibcall_value"
6416 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6417 (call (match_operand 1 "" "") (const_int 0)))
6422 (define_insn "*sibcall_value_symbolic_sp32"
6423 [(set (match_operand 0 "" "=rf")
6424 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6425 (match_operand 2 "" "")))
6428 "* return output_sibcall(insn, operands[1]);"
6429 [(set_attr "type" "sibcall")])
6431 (define_insn "*sibcall_value_symbolic_sp64"
6432 [(set (match_operand 0 "" "")
6433 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6434 (match_operand 2 "" "")))
6437 "* return output_sibcall(insn, operands[1]);"
6438 [(set_attr "type" "sibcall")])
6441 ;; Special instructions.
6443 (define_expand "prologue"
6448 sparc_flat_expand_prologue ();
6450 sparc_expand_prologue ();
6454 ;; The "register window save" insn is modelled as follows. The dwarf2
6455 ;; information is manually added in emit_window_save.
6457 (define_insn "window_save"
6459 [(match_operand 0 "arith_operand" "rI")]
6462 "save\t%%sp, %0, %%sp"
6463 [(set_attr "type" "savew")])
6465 (define_expand "epilogue"
6470 sparc_flat_expand_epilogue (false);
6472 sparc_expand_epilogue (false);
6475 (define_expand "sibcall_epilogue"
6480 sparc_flat_expand_epilogue (false);
6482 sparc_expand_epilogue (false);
6486 (define_expand "eh_return"
6487 [(use (match_operand 0 "general_operand" ""))]
6490 emit_move_insn (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), operands[0]);
6491 emit_jump_insn (gen_eh_return_internal ());
6496 (define_insn_and_split "eh_return_internal"
6500 "epilogue_completed"
6504 sparc_flat_expand_epilogue (true);
6506 sparc_expand_epilogue (true);
6509 (define_expand "return"
6511 "sparc_can_use_return_insn_p ()"
6514 (define_insn "*return_internal"
6517 "* return output_return (insn);"
6518 [(set_attr "type" "return")
6519 (set (attr "length")
6520 (cond [(eq_attr "calls_eh_return" "true")
6521 (if_then_else (eq_attr "delayed_branch" "true")
6522 (if_then_else (ior (eq_attr "isa" "v9")
6523 (eq_attr "flat" "true"))
6526 (if_then_else (eq_attr "flat" "true")
6529 (ior (eq_attr "leaf_function" "true") (eq_attr "flat" "true"))
6530 (if_then_else (eq_attr "empty_delay_slot" "true")
6533 (eq_attr "empty_delay_slot" "true")
6534 (if_then_else (eq_attr "delayed_branch" "true")
6539 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6540 ;; all of memory. This blocks insns from being moved across this point.
6542 (define_insn "blockage"
6543 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6546 [(set_attr "length" "0")])
6548 (define_expand "probe_stack"
6549 [(set (match_operand 0 "memory_operand" "") (const_int 0))]
6553 = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
6556 (define_insn "probe_stack_range<P:mode>"
6557 [(set (match_operand:P 0 "register_operand" "=r")
6558 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6559 (match_operand:P 2 "register_operand" "r")]
6560 UNSPECV_PROBE_STACK_RANGE))]
6562 "* return output_probe_stack_range (operands[0], operands[2]);"
6563 [(set_attr "type" "multi")])
6565 ;; Prepare to return any type including a structure value.
6567 (define_expand "untyped_return"
6568 [(match_operand:BLK 0 "memory_operand" "")
6569 (match_operand 1 "" "")]
6572 rtx valreg1 = gen_rtx_REG (DImode, 24);
6573 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6574 rtx result = operands[0];
6576 if (! TARGET_ARCH64)
6578 rtx rtnreg = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
6579 rtx value = gen_reg_rtx (SImode);
6581 /* Fetch the instruction where we will return to and see if it's an unimp
6582 instruction (the most significant 10 bits will be zero). If so,
6583 update the return address to skip the unimp instruction. */
6584 emit_move_insn (value,
6585 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
6586 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6587 emit_insn (gen_update_return (rtnreg, value));
6590 /* Reload the function value registers. */
6591 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6592 emit_move_insn (valreg2,
6593 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6595 /* Put USE insns before the return. */
6599 /* Construct the return. */
6600 expand_naked_return ();
6605 ;; Adjust the return address conditionally. If the value of op1 is equal
6606 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6607 ;; This is technically *half* the check required by the 32-bit SPARC
6608 ;; psABI. This check only ensures that an "unimp" insn was written by
6609 ;; the caller, but doesn't check to see if the expected size matches
6610 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6611 ;; only used by the above code "untyped_return".
6613 (define_insn "update_return"
6614 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6615 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6618 if (flag_delayed_branch)
6619 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6621 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6623 [(set (attr "type") (const_string "multi"))
6624 (set (attr "length")
6625 (if_then_else (eq_attr "delayed_branch" "true")
6634 (define_expand "indirect_jump"
6635 [(set (pc) (match_operand 0 "address_operand" "p"))]
6639 (define_insn "*branch_sp32"
6640 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6643 [(set_attr "type" "uncond_branch")])
6645 (define_insn "*branch_sp64"
6646 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6649 [(set_attr "type" "uncond_branch")])
6651 (define_expand "save_stack_nonlocal"
6652 [(set (match_operand 0 "memory_operand" "")
6653 (match_operand 1 "register_operand" ""))
6654 (set (match_dup 2) (match_dup 3))]
6657 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
6658 operands[2] = adjust_address_nv (operands[0], Pmode, GET_MODE_SIZE (Pmode));
6659 operands[3] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6662 (define_expand "restore_stack_nonlocal"
6663 [(set (match_operand 0 "register_operand" "")
6664 (match_operand 1 "memory_operand" ""))]
6667 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
6670 (define_expand "nonlocal_goto"
6671 [(match_operand 0 "general_operand" "")
6672 (match_operand 1 "general_operand" "")
6673 (match_operand 2 "memory_operand" "")
6674 (match_operand 3 "memory_operand" "")]
6677 rtx r_label = copy_to_reg (operands[1]);
6678 rtx r_sp = adjust_address_nv (operands[2], Pmode, 0);
6679 rtx r_fp = operands[3];
6680 rtx r_i7 = adjust_address_nv (operands[2], Pmode, GET_MODE_SIZE (Pmode));
6682 /* We need to flush all the register windows so that their contents will
6683 be re-synchronized by the restore insn of the target function. */
6685 emit_insn (gen_flush_register_windows ());
6687 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
6688 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
6690 /* Restore frame pointer for containing function. */
6691 emit_move_insn (hard_frame_pointer_rtx, r_fp);
6692 emit_stack_restore (SAVE_NONLOCAL, r_sp);
6694 /* USE of hard_frame_pointer_rtx added for consistency;
6695 not clear if really needed. */
6696 emit_use (hard_frame_pointer_rtx);
6697 emit_use (stack_pointer_rtx);
6699 /* We need to smuggle the load of %i7 as it is a fixed register. */
6700 emit_jump_insn (gen_nonlocal_goto_internal (r_label, r_i7));
6705 (define_insn "nonlocal_goto_internal"
6706 [(unspec_volatile [(match_operand 0 "register_operand" "r")
6707 (match_operand 1 "memory_operand" "m")] UNSPECV_GOTO)]
6708 "GET_MODE (operands[0]) == Pmode && GET_MODE (operands[1]) == Pmode"
6710 if (flag_delayed_branch)
6713 return "jmp\t%0\n\t ldx\t%1, %%i7";
6715 return "jmp\t%0\n\t ld\t%1, %%i7";
6720 return "ldx\t%1, %%i7\n\tjmp\t%0\n\t nop";
6722 return "ld\t%1, %%i7\n\tjmp\t%0\n\t nop";
6725 [(set (attr "type") (const_string "multi"))
6726 (set (attr "length")
6727 (if_then_else (eq_attr "delayed_branch" "true")
6731 (define_expand "builtin_setjmp_receiver"
6732 [(label_ref (match_operand 0 "" ""))]
6735 load_got_register ();
6739 ;; Special insn to flush register windows.
6741 (define_insn "flush_register_windows"
6742 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
6744 { return TARGET_V9 ? "flushw" : "ta\t3"; }
6745 [(set_attr "type" "flushw")])
6747 ;; Special pattern for the FLUSH instruction.
6749 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
6750 ; of the define_insn otherwise missing a mode. We make "flush", aka
6751 ; gen_flush, the default one since sparc_initialize_trampoline uses
6752 ; it on SImode mem values.
6754 (define_insn "flush"
6755 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6757 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6758 [(set_attr "type" "iflush")])
6760 (define_insn "flushdi"
6761 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6763 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6764 [(set_attr "type" "iflush")])
6767 ;; Find first set instructions.
6769 ;; The scan instruction searches from the most significant bit while ffs
6770 ;; searches from the least significant bit. The bit index and treatment of
6771 ;; zero also differ. It takes at least 7 instructions to get the proper
6772 ;; result. Here is an obvious 8 instruction sequence.
6775 (define_insn "ffssi2"
6776 [(set (match_operand:SI 0 "register_operand" "=&r")
6777 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
6778 (clobber (match_scratch:SI 2 "=&r"))]
6779 "TARGET_SPARCLITE || TARGET_SPARCLET"
6781 return "sub\t%%g0, %1, %0\;and\t%0, %1, %0\;scan\t%0, 0, %0\;mov\t32, %2\;sub\t%2, %0, %0\;sra\t%0, 31, %2\;and\t%2, 31, %2\;add\t%2, %0, %0";
6783 [(set_attr "type" "multi")
6784 (set_attr "length" "8")])
6786 ;; ??? This should be a define expand, so that the extra instruction have
6787 ;; a chance of being optimized away.
6789 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
6790 ;; does, but no one uses that and we don't have a switch for it.
6792 ;(define_insn "ffsdi2"
6793 ; [(set (match_operand:DI 0 "register_operand" "=&r")
6794 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
6795 ; (clobber (match_scratch:DI 2 "=&r"))]
6797 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
6798 ; [(set_attr "type" "multi")
6799 ; (set_attr "length" "4")])
6803 ;; Peepholes go at the end.
6805 ;; Optimize consecutive loads or stores into ldd and std when possible.
6806 ;; The conditions in which we do this are very restricted and are
6807 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
6810 [(set (match_operand:SI 0 "memory_operand" "")
6812 (set (match_operand:SI 1 "memory_operand" "")
6815 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
6818 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
6821 [(set (match_operand:SI 0 "memory_operand" "")
6823 (set (match_operand:SI 1 "memory_operand" "")
6826 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
6829 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
6832 [(set (match_operand:SI 0 "register_operand" "")
6833 (match_operand:SI 1 "memory_operand" ""))
6834 (set (match_operand:SI 2 "register_operand" "")
6835 (match_operand:SI 3 "memory_operand" ""))]
6836 "registers_ok_for_ldd_peep (operands[0], operands[2])
6837 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6840 "operands[1] = widen_memory_access (operands[1], DImode, 0);
6841 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
6844 [(set (match_operand:SI 0 "memory_operand" "")
6845 (match_operand:SI 1 "register_operand" ""))
6846 (set (match_operand:SI 2 "memory_operand" "")
6847 (match_operand:SI 3 "register_operand" ""))]
6848 "registers_ok_for_ldd_peep (operands[1], operands[3])
6849 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6852 "operands[0] = widen_memory_access (operands[0], DImode, 0);
6853 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
6856 [(set (match_operand:SF 0 "register_operand" "")
6857 (match_operand:SF 1 "memory_operand" ""))
6858 (set (match_operand:SF 2 "register_operand" "")
6859 (match_operand:SF 3 "memory_operand" ""))]
6860 "registers_ok_for_ldd_peep (operands[0], operands[2])
6861 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6864 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
6865 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
6868 [(set (match_operand:SF 0 "memory_operand" "")
6869 (match_operand:SF 1 "register_operand" ""))
6870 (set (match_operand:SF 2 "memory_operand" "")
6871 (match_operand:SF 3 "register_operand" ""))]
6872 "registers_ok_for_ldd_peep (operands[1], operands[3])
6873 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6876 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
6877 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
6880 [(set (match_operand:SI 0 "register_operand" "")
6881 (match_operand:SI 1 "memory_operand" ""))
6882 (set (match_operand:SI 2 "register_operand" "")
6883 (match_operand:SI 3 "memory_operand" ""))]
6884 "registers_ok_for_ldd_peep (operands[2], operands[0])
6885 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6888 "operands[3] = widen_memory_access (operands[3], DImode, 0);
6889 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
6892 [(set (match_operand:SI 0 "memory_operand" "")
6893 (match_operand:SI 1 "register_operand" ""))
6894 (set (match_operand:SI 2 "memory_operand" "")
6895 (match_operand:SI 3 "register_operand" ""))]
6896 "registers_ok_for_ldd_peep (operands[3], operands[1])
6897 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6900 "operands[2] = widen_memory_access (operands[2], DImode, 0);
6901 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
6905 [(set (match_operand:SF 0 "register_operand" "")
6906 (match_operand:SF 1 "memory_operand" ""))
6907 (set (match_operand:SF 2 "register_operand" "")
6908 (match_operand:SF 3 "memory_operand" ""))]
6909 "registers_ok_for_ldd_peep (operands[2], operands[0])
6910 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6913 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
6914 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
6917 [(set (match_operand:SF 0 "memory_operand" "")
6918 (match_operand:SF 1 "register_operand" ""))
6919 (set (match_operand:SF 2 "memory_operand" "")
6920 (match_operand:SF 3 "register_operand" ""))]
6921 "registers_ok_for_ldd_peep (operands[3], operands[1])
6922 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6925 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
6926 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
6928 ;; Optimize the case of following a reg-reg move with a test
6929 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
6930 ;; This can result from a float to fix conversion.
6933 [(set (match_operand:SI 0 "register_operand" "")
6934 (match_operand:SI 1 "register_operand" ""))
6935 (set (reg:CC CC_REG)
6936 (compare:CC (match_operand:SI 2 "register_operand" "")
6938 "(rtx_equal_p (operands[2], operands[0])
6939 || rtx_equal_p (operands[2], operands[1]))
6940 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6941 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6942 [(parallel [(set (match_dup 0) (match_dup 1))
6943 (set (reg:CC CC_REG)
6944 (compare:CC (match_dup 1) (const_int 0)))])]
6948 [(set (match_operand:DI 0 "register_operand" "")
6949 (match_operand:DI 1 "register_operand" ""))
6950 (set (reg:CCX CC_REG)
6951 (compare:CCX (match_operand:DI 2 "register_operand" "")
6954 && (rtx_equal_p (operands[2], operands[0])
6955 || rtx_equal_p (operands[2], operands[1]))
6956 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6957 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6958 [(parallel [(set (match_dup 0) (match_dup 1))
6959 (set (reg:CCX CC_REG)
6960 (compare:CCX (match_dup 1) (const_int 0)))])]
6964 ;; Prefetch instructions.
6966 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
6967 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
6968 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
6970 (define_expand "prefetch"
6971 [(match_operand 0 "address_operand" "")
6972 (match_operand 1 "const_int_operand" "")
6973 (match_operand 2 "const_int_operand" "")]
6977 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
6979 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
6983 (define_insn "prefetch_64"
6984 [(prefetch (match_operand:DI 0 "address_operand" "p")
6985 (match_operand:DI 1 "const_int_operand" "n")
6986 (match_operand:DI 2 "const_int_operand" "n"))]
6989 static const char * const prefetch_instr[2][2] = {
6991 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
6992 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
6995 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
6996 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
6999 int read_or_write = INTVAL (operands[1]);
7000 int locality = INTVAL (operands[2]);
7002 gcc_assert (read_or_write == 0 || read_or_write == 1);
7003 gcc_assert (locality >= 0 && locality < 4);
7004 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7006 [(set_attr "type" "load")])
7008 (define_insn "prefetch_32"
7009 [(prefetch (match_operand:SI 0 "address_operand" "p")
7010 (match_operand:SI 1 "const_int_operand" "n")
7011 (match_operand:SI 2 "const_int_operand" "n"))]
7014 static const char * const prefetch_instr[2][2] = {
7016 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7017 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7020 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7021 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7024 int read_or_write = INTVAL (operands[1]);
7025 int locality = INTVAL (operands[2]);
7027 gcc_assert (read_or_write == 0 || read_or_write == 1);
7028 gcc_assert (locality >= 0 && locality < 4);
7029 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7031 [(set_attr "type" "load")])
7034 ;; Trap instructions.
7037 [(trap_if (const_int 1) (const_int 5))]
7040 [(set_attr "type" "trap")])
7042 (define_expand "ctrapsi4"
7043 [(trap_if (match_operator 0 "noov_compare_operator"
7044 [(match_operand:SI 1 "compare_operand" "")
7045 (match_operand:SI 2 "arith_operand" "")])
7046 (match_operand 3 ""))]
7048 "operands[1] = gen_compare_reg (operands[0]);
7049 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7051 operands[2] = const0_rtx;")
7053 (define_expand "ctrapdi4"
7054 [(trap_if (match_operator 0 "noov_compare_operator"
7055 [(match_operand:DI 1 "compare_operand" "")
7056 (match_operand:DI 2 "arith_operand" "")])
7057 (match_operand 3 ""))]
7059 "operands[1] = gen_compare_reg (operands[0]);
7060 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7062 operands[2] = const0_rtx;")
7066 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC CC_REG) (const_int 0)])
7067 (match_operand:SI 1 "arith_operand" "rM"))]
7071 return "t%C0\t%%icc, %1";
7075 [(set_attr "type" "trap")])
7078 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX CC_REG) (const_int 0)])
7079 (match_operand:SI 1 "arith_operand" "rM"))]
7082 [(set_attr "type" "trap")])
7085 ;; TLS support instructions.
7087 (define_insn "tgd_hi22"
7088 [(set (match_operand:SI 0 "register_operand" "=r")
7089 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7092 "sethi\\t%%tgd_hi22(%a1), %0")
7094 (define_insn "tgd_lo10"
7095 [(set (match_operand:SI 0 "register_operand" "=r")
7096 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7097 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7100 "add\\t%1, %%tgd_lo10(%a2), %0")
7102 (define_insn "tgd_add32"
7103 [(set (match_operand:SI 0 "register_operand" "=r")
7104 (plus:SI (match_operand:SI 1 "register_operand" "r")
7105 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7106 (match_operand 3 "tgd_symbolic_operand" "")]
7108 "TARGET_TLS && TARGET_ARCH32"
7109 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7111 (define_insn "tgd_add64"
7112 [(set (match_operand:DI 0 "register_operand" "=r")
7113 (plus:DI (match_operand:DI 1 "register_operand" "r")
7114 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7115 (match_operand 3 "tgd_symbolic_operand" "")]
7117 "TARGET_TLS && TARGET_ARCH64"
7118 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7120 (define_insn "tgd_call32"
7121 [(set (match_operand 0 "register_operand" "=r")
7122 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7123 (match_operand 2 "tgd_symbolic_operand" "")]
7125 (match_operand 3 "" "")))
7126 (clobber (reg:SI O7_REG))]
7127 "TARGET_TLS && TARGET_ARCH32"
7128 "call\t%a1, %%tgd_call(%a2)%#"
7129 [(set_attr "type" "call")])
7131 (define_insn "tgd_call64"
7132 [(set (match_operand 0 "register_operand" "=r")
7133 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7134 (match_operand 2 "tgd_symbolic_operand" "")]
7136 (match_operand 3 "" "")))
7137 (clobber (reg:DI O7_REG))]
7138 "TARGET_TLS && TARGET_ARCH64"
7139 "call\t%a1, %%tgd_call(%a2)%#"
7140 [(set_attr "type" "call")])
7142 (define_insn "tldm_hi22"
7143 [(set (match_operand:SI 0 "register_operand" "=r")
7144 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7146 "sethi\\t%%tldm_hi22(%&), %0")
7148 (define_insn "tldm_lo10"
7149 [(set (match_operand:SI 0 "register_operand" "=r")
7150 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7151 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7153 "add\\t%1, %%tldm_lo10(%&), %0")
7155 (define_insn "tldm_add32"
7156 [(set (match_operand:SI 0 "register_operand" "=r")
7157 (plus:SI (match_operand:SI 1 "register_operand" "r")
7158 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7160 "TARGET_TLS && TARGET_ARCH32"
7161 "add\\t%1, %2, %0, %%tldm_add(%&)")
7163 (define_insn "tldm_add64"
7164 [(set (match_operand:DI 0 "register_operand" "=r")
7165 (plus:DI (match_operand:DI 1 "register_operand" "r")
7166 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7168 "TARGET_TLS && TARGET_ARCH64"
7169 "add\\t%1, %2, %0, %%tldm_add(%&)")
7171 (define_insn "tldm_call32"
7172 [(set (match_operand 0 "register_operand" "=r")
7173 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7175 (match_operand 2 "" "")))
7176 (clobber (reg:SI O7_REG))]
7177 "TARGET_TLS && TARGET_ARCH32"
7178 "call\t%a1, %%tldm_call(%&)%#"
7179 [(set_attr "type" "call")])
7181 (define_insn "tldm_call64"
7182 [(set (match_operand 0 "register_operand" "=r")
7183 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7185 (match_operand 2 "" "")))
7186 (clobber (reg:DI O7_REG))]
7187 "TARGET_TLS && TARGET_ARCH64"
7188 "call\t%a1, %%tldm_call(%&)%#"
7189 [(set_attr "type" "call")])
7191 (define_insn "tldo_hix22"
7192 [(set (match_operand:SI 0 "register_operand" "=r")
7193 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7196 "sethi\\t%%tldo_hix22(%a1), %0")
7198 (define_insn "tldo_lox10"
7199 [(set (match_operand:SI 0 "register_operand" "=r")
7200 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7201 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7204 "xor\\t%1, %%tldo_lox10(%a2), %0")
7206 (define_insn "tldo_add32"
7207 [(set (match_operand:SI 0 "register_operand" "=r")
7208 (plus:SI (match_operand:SI 1 "register_operand" "r")
7209 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7210 (match_operand 3 "tld_symbolic_operand" "")]
7212 "TARGET_TLS && TARGET_ARCH32"
7213 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7215 (define_insn "tldo_add64"
7216 [(set (match_operand:DI 0 "register_operand" "=r")
7217 (plus:DI (match_operand:DI 1 "register_operand" "r")
7218 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7219 (match_operand 3 "tld_symbolic_operand" "")]
7221 "TARGET_TLS && TARGET_ARCH64"
7222 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7224 (define_insn "tie_hi22"
7225 [(set (match_operand:SI 0 "register_operand" "=r")
7226 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7229 "sethi\\t%%tie_hi22(%a1), %0")
7231 (define_insn "tie_lo10"
7232 [(set (match_operand:SI 0 "register_operand" "=r")
7233 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7234 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7237 "add\\t%1, %%tie_lo10(%a2), %0")
7239 (define_insn "tie_ld32"
7240 [(set (match_operand:SI 0 "register_operand" "=r")
7241 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7242 (match_operand:SI 2 "register_operand" "r")
7243 (match_operand 3 "tie_symbolic_operand" "")]
7245 "TARGET_TLS && TARGET_ARCH32"
7246 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7247 [(set_attr "type" "load")])
7249 (define_insn "tie_ld64"
7250 [(set (match_operand:DI 0 "register_operand" "=r")
7251 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7252 (match_operand:SI 2 "register_operand" "r")
7253 (match_operand 3 "tie_symbolic_operand" "")]
7255 "TARGET_TLS && TARGET_ARCH64"
7256 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7257 [(set_attr "type" "load")])
7259 (define_insn "tie_add32"
7260 [(set (match_operand:SI 0 "register_operand" "=r")
7261 (plus:SI (match_operand:SI 1 "register_operand" "r")
7262 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7263 (match_operand 3 "tie_symbolic_operand" "")]
7265 "TARGET_SUN_TLS && TARGET_ARCH32"
7266 "add\\t%1, %2, %0, %%tie_add(%a3)")
7268 (define_insn "tie_add64"
7269 [(set (match_operand:DI 0 "register_operand" "=r")
7270 (plus:DI (match_operand:DI 1 "register_operand" "r")
7271 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7272 (match_operand 3 "tie_symbolic_operand" "")]
7274 "TARGET_SUN_TLS && TARGET_ARCH64"
7275 "add\\t%1, %2, %0, %%tie_add(%a3)")
7277 (define_insn "tle_hix22_sp32"
7278 [(set (match_operand:SI 0 "register_operand" "=r")
7279 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7281 "TARGET_TLS && TARGET_ARCH32"
7282 "sethi\\t%%tle_hix22(%a1), %0")
7284 (define_insn "tle_lox10_sp32"
7285 [(set (match_operand:SI 0 "register_operand" "=r")
7286 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7287 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7289 "TARGET_TLS && TARGET_ARCH32"
7290 "xor\\t%1, %%tle_lox10(%a2), %0")
7292 (define_insn "tle_hix22_sp64"
7293 [(set (match_operand:DI 0 "register_operand" "=r")
7294 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7296 "TARGET_TLS && TARGET_ARCH64"
7297 "sethi\\t%%tle_hix22(%a1), %0")
7299 (define_insn "tle_lox10_sp64"
7300 [(set (match_operand:DI 0 "register_operand" "=r")
7301 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7302 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7304 "TARGET_TLS && TARGET_ARCH64"
7305 "xor\\t%1, %%tle_lox10(%a2), %0")
7307 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7308 (define_insn "*tldo_ldub_sp32"
7309 [(set (match_operand:QI 0 "register_operand" "=r")
7310 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7311 (match_operand 3 "tld_symbolic_operand" "")]
7313 (match_operand:SI 1 "register_operand" "r"))))]
7314 "TARGET_TLS && TARGET_ARCH32"
7315 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7316 [(set_attr "type" "load")
7317 (set_attr "us3load_type" "3cycle")])
7319 (define_insn "*tldo_ldub1_sp32"
7320 [(set (match_operand:HI 0 "register_operand" "=r")
7321 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7322 (match_operand 3 "tld_symbolic_operand" "")]
7324 (match_operand:SI 1 "register_operand" "r")))))]
7325 "TARGET_TLS && TARGET_ARCH32"
7326 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7327 [(set_attr "type" "load")
7328 (set_attr "us3load_type" "3cycle")])
7330 (define_insn "*tldo_ldub2_sp32"
7331 [(set (match_operand:SI 0 "register_operand" "=r")
7332 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7333 (match_operand 3 "tld_symbolic_operand" "")]
7335 (match_operand:SI 1 "register_operand" "r")))))]
7336 "TARGET_TLS && TARGET_ARCH32"
7337 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7338 [(set_attr "type" "load")
7339 (set_attr "us3load_type" "3cycle")])
7341 (define_insn "*tldo_ldsb1_sp32"
7342 [(set (match_operand:HI 0 "register_operand" "=r")
7343 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7344 (match_operand 3 "tld_symbolic_operand" "")]
7346 (match_operand:SI 1 "register_operand" "r")))))]
7347 "TARGET_TLS && TARGET_ARCH32"
7348 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7349 [(set_attr "type" "sload")
7350 (set_attr "us3load_type" "3cycle")])
7352 (define_insn "*tldo_ldsb2_sp32"
7353 [(set (match_operand:SI 0 "register_operand" "=r")
7354 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7355 (match_operand 3 "tld_symbolic_operand" "")]
7357 (match_operand:SI 1 "register_operand" "r")))))]
7358 "TARGET_TLS && TARGET_ARCH32"
7359 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7360 [(set_attr "type" "sload")
7361 (set_attr "us3load_type" "3cycle")])
7363 (define_insn "*tldo_ldub_sp64"
7364 [(set (match_operand:QI 0 "register_operand" "=r")
7365 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7366 (match_operand 3 "tld_symbolic_operand" "")]
7368 (match_operand:DI 1 "register_operand" "r"))))]
7369 "TARGET_TLS && TARGET_ARCH64"
7370 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7371 [(set_attr "type" "load")
7372 (set_attr "us3load_type" "3cycle")])
7374 (define_insn "*tldo_ldub1_sp64"
7375 [(set (match_operand:HI 0 "register_operand" "=r")
7376 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7377 (match_operand 3 "tld_symbolic_operand" "")]
7379 (match_operand:DI 1 "register_operand" "r")))))]
7380 "TARGET_TLS && TARGET_ARCH64"
7381 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7382 [(set_attr "type" "load")
7383 (set_attr "us3load_type" "3cycle")])
7385 (define_insn "*tldo_ldub2_sp64"
7386 [(set (match_operand:SI 0 "register_operand" "=r")
7387 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7388 (match_operand 3 "tld_symbolic_operand" "")]
7390 (match_operand:DI 1 "register_operand" "r")))))]
7391 "TARGET_TLS && TARGET_ARCH64"
7392 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7393 [(set_attr "type" "load")
7394 (set_attr "us3load_type" "3cycle")])
7396 (define_insn "*tldo_ldub3_sp64"
7397 [(set (match_operand:DI 0 "register_operand" "=r")
7398 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7399 (match_operand 3 "tld_symbolic_operand" "")]
7401 (match_operand:DI 1 "register_operand" "r")))))]
7402 "TARGET_TLS && TARGET_ARCH64"
7403 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7404 [(set_attr "type" "load")
7405 (set_attr "us3load_type" "3cycle")])
7407 (define_insn "*tldo_ldsb1_sp64"
7408 [(set (match_operand:HI 0 "register_operand" "=r")
7409 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7410 (match_operand 3 "tld_symbolic_operand" "")]
7412 (match_operand:DI 1 "register_operand" "r")))))]
7413 "TARGET_TLS && TARGET_ARCH64"
7414 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7415 [(set_attr "type" "sload")
7416 (set_attr "us3load_type" "3cycle")])
7418 (define_insn "*tldo_ldsb2_sp64"
7419 [(set (match_operand:SI 0 "register_operand" "=r")
7420 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7421 (match_operand 3 "tld_symbolic_operand" "")]
7423 (match_operand:DI 1 "register_operand" "r")))))]
7424 "TARGET_TLS && TARGET_ARCH64"
7425 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7426 [(set_attr "type" "sload")
7427 (set_attr "us3load_type" "3cycle")])
7429 (define_insn "*tldo_ldsb3_sp64"
7430 [(set (match_operand:DI 0 "register_operand" "=r")
7431 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7432 (match_operand 3 "tld_symbolic_operand" "")]
7434 (match_operand:DI 1 "register_operand" "r")))))]
7435 "TARGET_TLS && TARGET_ARCH64"
7436 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7437 [(set_attr "type" "sload")
7438 (set_attr "us3load_type" "3cycle")])
7440 (define_insn "*tldo_lduh_sp32"
7441 [(set (match_operand:HI 0 "register_operand" "=r")
7442 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7443 (match_operand 3 "tld_symbolic_operand" "")]
7445 (match_operand:SI 1 "register_operand" "r"))))]
7446 "TARGET_TLS && TARGET_ARCH32"
7447 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7448 [(set_attr "type" "load")
7449 (set_attr "us3load_type" "3cycle")])
7451 (define_insn "*tldo_lduh1_sp32"
7452 [(set (match_operand:SI 0 "register_operand" "=r")
7453 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7454 (match_operand 3 "tld_symbolic_operand" "")]
7456 (match_operand:SI 1 "register_operand" "r")))))]
7457 "TARGET_TLS && TARGET_ARCH32"
7458 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7459 [(set_attr "type" "load")
7460 (set_attr "us3load_type" "3cycle")])
7462 (define_insn "*tldo_ldsh1_sp32"
7463 [(set (match_operand:SI 0 "register_operand" "=r")
7464 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7465 (match_operand 3 "tld_symbolic_operand" "")]
7467 (match_operand:SI 1 "register_operand" "r")))))]
7468 "TARGET_TLS && TARGET_ARCH32"
7469 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7470 [(set_attr "type" "sload")
7471 (set_attr "us3load_type" "3cycle")])
7473 (define_insn "*tldo_lduh_sp64"
7474 [(set (match_operand:HI 0 "register_operand" "=r")
7475 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7476 (match_operand 3 "tld_symbolic_operand" "")]
7478 (match_operand:DI 1 "register_operand" "r"))))]
7479 "TARGET_TLS && TARGET_ARCH64"
7480 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7481 [(set_attr "type" "load")
7482 (set_attr "us3load_type" "3cycle")])
7484 (define_insn "*tldo_lduh1_sp64"
7485 [(set (match_operand:SI 0 "register_operand" "=r")
7486 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7487 (match_operand 3 "tld_symbolic_operand" "")]
7489 (match_operand:DI 1 "register_operand" "r")))))]
7490 "TARGET_TLS && TARGET_ARCH64"
7491 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7492 [(set_attr "type" "load")
7493 (set_attr "us3load_type" "3cycle")])
7495 (define_insn "*tldo_lduh2_sp64"
7496 [(set (match_operand:DI 0 "register_operand" "=r")
7497 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7498 (match_operand 3 "tld_symbolic_operand" "")]
7500 (match_operand:DI 1 "register_operand" "r")))))]
7501 "TARGET_TLS && TARGET_ARCH64"
7502 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7503 [(set_attr "type" "load")
7504 (set_attr "us3load_type" "3cycle")])
7506 (define_insn "*tldo_ldsh1_sp64"
7507 [(set (match_operand:SI 0 "register_operand" "=r")
7508 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7509 (match_operand 3 "tld_symbolic_operand" "")]
7511 (match_operand:DI 1 "register_operand" "r")))))]
7512 "TARGET_TLS && TARGET_ARCH64"
7513 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7514 [(set_attr "type" "sload")
7515 (set_attr "us3load_type" "3cycle")])
7517 (define_insn "*tldo_ldsh2_sp64"
7518 [(set (match_operand:DI 0 "register_operand" "=r")
7519 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7520 (match_operand 3 "tld_symbolic_operand" "")]
7522 (match_operand:DI 1 "register_operand" "r")))))]
7523 "TARGET_TLS && TARGET_ARCH64"
7524 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7525 [(set_attr "type" "sload")
7526 (set_attr "us3load_type" "3cycle")])
7528 (define_insn "*tldo_lduw_sp32"
7529 [(set (match_operand:SI 0 "register_operand" "=r")
7530 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7531 (match_operand 3 "tld_symbolic_operand" "")]
7533 (match_operand:SI 1 "register_operand" "r"))))]
7534 "TARGET_TLS && TARGET_ARCH32"
7535 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7536 [(set_attr "type" "load")])
7538 (define_insn "*tldo_lduw_sp64"
7539 [(set (match_operand:SI 0 "register_operand" "=r")
7540 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7541 (match_operand 3 "tld_symbolic_operand" "")]
7543 (match_operand:DI 1 "register_operand" "r"))))]
7544 "TARGET_TLS && TARGET_ARCH64"
7545 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7546 [(set_attr "type" "load")])
7548 (define_insn "*tldo_lduw1_sp64"
7549 [(set (match_operand:DI 0 "register_operand" "=r")
7550 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7551 (match_operand 3 "tld_symbolic_operand" "")]
7553 (match_operand:DI 1 "register_operand" "r")))))]
7554 "TARGET_TLS && TARGET_ARCH64"
7555 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7556 [(set_attr "type" "load")])
7558 (define_insn "*tldo_ldsw1_sp64"
7559 [(set (match_operand:DI 0 "register_operand" "=r")
7560 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7561 (match_operand 3 "tld_symbolic_operand" "")]
7563 (match_operand:DI 1 "register_operand" "r")))))]
7564 "TARGET_TLS && TARGET_ARCH64"
7565 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7566 [(set_attr "type" "sload")
7567 (set_attr "us3load_type" "3cycle")])
7569 (define_insn "*tldo_ldx_sp64"
7570 [(set (match_operand:DI 0 "register_operand" "=r")
7571 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7572 (match_operand 3 "tld_symbolic_operand" "")]
7574 (match_operand:DI 1 "register_operand" "r"))))]
7575 "TARGET_TLS && TARGET_ARCH64"
7576 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7577 [(set_attr "type" "load")])
7579 (define_insn "*tldo_stb_sp32"
7580 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7581 (match_operand 3 "tld_symbolic_operand" "")]
7583 (match_operand:SI 1 "register_operand" "r")))
7584 (match_operand:QI 0 "register_operand" "=r"))]
7585 "TARGET_TLS && TARGET_ARCH32"
7586 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7587 [(set_attr "type" "store")])
7589 (define_insn "*tldo_stb_sp64"
7590 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7591 (match_operand 3 "tld_symbolic_operand" "")]
7593 (match_operand:DI 1 "register_operand" "r")))
7594 (match_operand:QI 0 "register_operand" "=r"))]
7595 "TARGET_TLS && TARGET_ARCH64"
7596 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7597 [(set_attr "type" "store")])
7599 (define_insn "*tldo_sth_sp32"
7600 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7601 (match_operand 3 "tld_symbolic_operand" "")]
7603 (match_operand:SI 1 "register_operand" "r")))
7604 (match_operand:HI 0 "register_operand" "=r"))]
7605 "TARGET_TLS && TARGET_ARCH32"
7606 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7607 [(set_attr "type" "store")])
7609 (define_insn "*tldo_sth_sp64"
7610 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7611 (match_operand 3 "tld_symbolic_operand" "")]
7613 (match_operand:DI 1 "register_operand" "r")))
7614 (match_operand:HI 0 "register_operand" "=r"))]
7615 "TARGET_TLS && TARGET_ARCH64"
7616 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7617 [(set_attr "type" "store")])
7619 (define_insn "*tldo_stw_sp32"
7620 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7621 (match_operand 3 "tld_symbolic_operand" "")]
7623 (match_operand:SI 1 "register_operand" "r")))
7624 (match_operand:SI 0 "register_operand" "=r"))]
7625 "TARGET_TLS && TARGET_ARCH32"
7626 "st\t%0, [%1 + %2], %%tldo_add(%3)"
7627 [(set_attr "type" "store")])
7629 (define_insn "*tldo_stw_sp64"
7630 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7631 (match_operand 3 "tld_symbolic_operand" "")]
7633 (match_operand:DI 1 "register_operand" "r")))
7634 (match_operand:SI 0 "register_operand" "=r"))]
7635 "TARGET_TLS && TARGET_ARCH64"
7636 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7637 [(set_attr "type" "store")])
7639 (define_insn "*tldo_stx_sp64"
7640 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7641 (match_operand 3 "tld_symbolic_operand" "")]
7643 (match_operand:DI 1 "register_operand" "r")))
7644 (match_operand:DI 0 "register_operand" "=r"))]
7645 "TARGET_TLS && TARGET_ARCH64"
7646 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7647 [(set_attr "type" "store")])
7650 ;; Stack protector instructions.
7652 (define_expand "stack_protect_set"
7653 [(match_operand 0 "memory_operand" "")
7654 (match_operand 1 "memory_operand" "")]
7657 #ifdef TARGET_THREAD_SSP_OFFSET
7658 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7659 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7660 operands[1] = gen_rtx_MEM (Pmode, addr);
7663 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7665 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7669 (define_insn "stack_protect_setsi"
7670 [(set (match_operand:SI 0 "memory_operand" "=m")
7671 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7672 (set (match_scratch:SI 2 "=&r") (const_int 0))]
7674 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
7675 [(set_attr "type" "multi")
7676 (set_attr "length" "3")])
7678 (define_insn "stack_protect_setdi"
7679 [(set (match_operand:DI 0 "memory_operand" "=m")
7680 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7681 (set (match_scratch:DI 2 "=&r") (const_int 0))]
7683 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
7684 [(set_attr "type" "multi")
7685 (set_attr "length" "3")])
7687 (define_expand "stack_protect_test"
7688 [(match_operand 0 "memory_operand" "")
7689 (match_operand 1 "memory_operand" "")
7690 (match_operand 2 "" "")]
7694 #ifdef TARGET_THREAD_SSP_OFFSET
7695 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7696 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7697 operands[1] = gen_rtx_MEM (Pmode, addr);
7701 result = gen_reg_rtx (Pmode);
7702 emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
7703 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7704 emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
7708 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7709 result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
7710 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7711 emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
7716 (define_insn "stack_protect_testsi"
7717 [(set (reg:CC CC_REG)
7718 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
7719 (match_operand:SI 1 "memory_operand" "m")]
7721 (set (match_scratch:SI 3 "=r") (const_int 0))
7722 (clobber (match_scratch:SI 2 "=&r"))]
7724 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
7725 [(set_attr "type" "multi")
7726 (set_attr "length" "4")])
7728 (define_insn "stack_protect_testdi"
7729 [(set (match_operand:DI 0 "register_operand" "=&r")
7730 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7731 (match_operand:DI 2 "memory_operand" "m")]
7733 (set (match_scratch:DI 3 "=r") (const_int 0))]
7735 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
7736 [(set_attr "type" "multi")
7737 (set_attr "length" "4")])
7740 ;; Vector instructions.
7742 (define_insn "addv2si3"
7743 [(set (match_operand:V2SI 0 "register_operand" "=e")
7744 (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7745 (match_operand:V2SI 2 "register_operand" "e")))]
7747 "fpadd32\t%1, %2, %0"
7748 [(set_attr "type" "fga")
7749 (set_attr "fptype" "double")])
7751 (define_insn "addv4hi3"
7752 [(set (match_operand:V4HI 0 "register_operand" "=e")
7753 (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7754 (match_operand:V4HI 2 "register_operand" "e")))]
7756 "fpadd16\t%1, %2, %0"
7757 [(set_attr "type" "fga")
7758 (set_attr "fptype" "double")])
7760 ;; fpadd32s is emitted by the addsi3 pattern.
7762 (define_insn "addv2hi3"
7763 [(set (match_operand:V2HI 0 "register_operand" "=f")
7764 (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7765 (match_operand:V2HI 2 "register_operand" "f")))]
7767 "fpadd16s\t%1, %2, %0"
7768 [(set_attr "type" "fga")
7769 (set_attr "fptype" "single")])
7771 (define_insn "subv2si3"
7772 [(set (match_operand:V2SI 0 "register_operand" "=e")
7773 (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7774 (match_operand:V2SI 2 "register_operand" "e")))]
7776 "fpsub32\t%1, %2, %0"
7777 [(set_attr "type" "fga")
7778 (set_attr "fptype" "double")])
7780 (define_insn "subv4hi3"
7781 [(set (match_operand:V4HI 0 "register_operand" "=e")
7782 (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7783 (match_operand:V4HI 2 "register_operand" "e")))]
7785 "fpsub16\t%1, %2, %0"
7786 [(set_attr "type" "fga")
7787 (set_attr "fptype" "double")])
7789 ;; fpsub32s is emitted by the subsi3 pattern.
7791 (define_insn "subv2hi3"
7792 [(set (match_operand:V2HI 0 "register_operand" "=f")
7793 (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7794 (match_operand:V2HI 2 "register_operand" "f")))]
7796 "fpsub16s\t%1, %2, %0"
7797 [(set_attr "type" "fga")
7798 (set_attr "fptype" "single")])
7800 ;; All other logical instructions have integer equivalents so they
7801 ;; are defined together.
7803 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
7805 (define_insn "*nand<V64:mode>_vis"
7806 [(set (match_operand:V64 0 "register_operand" "=e")
7807 (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
7808 (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
7811 [(set_attr "type" "fga")
7812 (set_attr "fptype" "double")])
7814 (define_insn "*nand<V32:mode>_vis"
7815 [(set (match_operand:V32 0 "register_operand" "=f")
7816 (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
7817 (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
7819 "fnands\t%1, %2, %0"
7820 [(set_attr "type" "fga")
7821 (set_attr "fptype" "single")])
7823 ;; Hard to generate VIS instructions. We have builtins for these.
7825 (define_insn "fpack16_vis"
7826 [(set (match_operand:V4QI 0 "register_operand" "=f")
7827 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
7829 (use (reg:DI GSR_REG))]
7832 [(set_attr "type" "fga")
7833 (set_attr "fptype" "double")])
7835 (define_insn "fpackfix_vis"
7836 [(set (match_operand:V2HI 0 "register_operand" "=f")
7837 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
7839 (use (reg:DI GSR_REG))]
7842 [(set_attr "type" "fga")
7843 (set_attr "fptype" "double")])
7845 (define_insn "fpack32_vis"
7846 [(set (match_operand:V8QI 0 "register_operand" "=e")
7847 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
7848 (match_operand:V8QI 2 "register_operand" "e")]
7850 (use (reg:DI GSR_REG))]
7852 "fpack32\t%1, %2, %0"
7853 [(set_attr "type" "fga")
7854 (set_attr "fptype" "double")])
7856 (define_insn "fexpand_vis"
7857 [(set (match_operand:V4HI 0 "register_operand" "=e")
7858 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
7862 [(set_attr "type" "fga")
7863 (set_attr "fptype" "double")])
7865 ;; It may be possible to describe this operation as (1 indexed):
7866 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
7867 ;; 1,5,10,14,19,23,28,32)
7868 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
7869 ;; because vec_merge expects all the operands to be of the same type.
7870 (define_insn "fpmerge_vis"
7871 [(set (match_operand:V8QI 0 "register_operand" "=e")
7872 (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
7873 (match_operand:V4QI 2 "register_operand" "f")]
7876 "fpmerge\t%1, %2, %0"
7877 [(set_attr "type" "fga")
7878 (set_attr "fptype" "double")])
7880 ;; Partitioned multiply instructions
7881 (define_insn "fmul8x16_vis"
7882 [(set (match_operand:V4HI 0 "register_operand" "=e")
7883 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7884 (match_operand:V4HI 2 "register_operand" "e")))]
7886 "fmul8x16\t%1, %2, %0"
7887 [(set_attr "type" "fpmul")
7888 (set_attr "fptype" "double")])
7890 ;; Only one of the following two insns can be a multiply.
7891 (define_insn "fmul8x16au_vis"
7892 [(set (match_operand:V4HI 0 "register_operand" "=e")
7893 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7894 (match_operand:V2HI 2 "register_operand" "f")))]
7896 "fmul8x16au\t%1, %2, %0"
7897 [(set_attr "type" "fpmul")
7898 (set_attr "fptype" "double")])
7900 (define_insn "fmul8x16al_vis"
7901 [(set (match_operand:V4HI 0 "register_operand" "=e")
7902 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
7903 (match_operand:V2HI 2 "register_operand" "f")]
7906 "fmul8x16al\t%1, %2, %0"
7907 [(set_attr "type" "fpmul")
7908 (set_attr "fptype" "double")])
7910 ;; Only one of the following two insns can be a multiply.
7911 (define_insn "fmul8sux16_vis"
7912 [(set (match_operand:V4HI 0 "register_operand" "=e")
7913 (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
7914 (match_operand:V4HI 2 "register_operand" "e")))]
7916 "fmul8sux16\t%1, %2, %0"
7917 [(set_attr "type" "fpmul")
7918 (set_attr "fptype" "double")])
7920 (define_insn "fmul8ulx16_vis"
7921 [(set (match_operand:V4HI 0 "register_operand" "=e")
7922 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
7923 (match_operand:V4HI 2 "register_operand" "e")]
7926 "fmul8ulx16\t%1, %2, %0"
7927 [(set_attr "type" "fpmul")
7928 (set_attr "fptype" "double")])
7930 ;; Only one of the following two insns can be a multiply.
7931 (define_insn "fmuld8sux16_vis"
7932 [(set (match_operand:V2SI 0 "register_operand" "=e")
7933 (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
7934 (match_operand:V2HI 2 "register_operand" "f")))]
7936 "fmuld8sux16\t%1, %2, %0"
7937 [(set_attr "type" "fpmul")
7938 (set_attr "fptype" "double")])
7940 (define_insn "fmuld8ulx16_vis"
7941 [(set (match_operand:V2SI 0 "register_operand" "=e")
7942 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
7943 (match_operand:V2HI 2 "register_operand" "f")]
7946 "fmuld8ulx16\t%1, %2, %0"
7947 [(set_attr "type" "fpmul")
7948 (set_attr "fptype" "double")])
7950 (define_expand "wrgsr_vis"
7951 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" ""))]
7954 if (! TARGET_ARCH64)
7956 emit_insn (gen_wrgsr_v8plus (operands[0]));
7961 (define_insn "*wrgsr_sp64"
7962 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "rI"))]
7963 "TARGET_VIS && TARGET_ARCH64"
7964 "wr\t%%g0, %0, %%gsr"
7965 [(set_attr "type" "gsr")])
7967 (define_insn "wrgsr_v8plus"
7968 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "I,r"))
7969 (clobber (match_scratch:SI 1 "=X,&h"))]
7970 "TARGET_VIS && ! TARGET_ARCH64"
7972 if (GET_CODE (operands[0]) == CONST_INT
7973 || sparc_check_64 (operands[0], insn))
7974 return "wr\t%%g0, %0, %%gsr";
7976 output_asm_insn("srl\t%L0, 0, %L0", operands);
7977 return "sllx\t%H0, 32, %1\n\tor\t%L0, %1, %1\n\twr\t%%g0, %1, %%gsr";
7979 [(set_attr "type" "multi")])
7981 (define_expand "rdgsr_vis"
7982 [(set (match_operand:DI 0 "register_operand" "") (reg:DI GSR_REG))]
7985 if (! TARGET_ARCH64)
7987 emit_insn (gen_rdgsr_v8plus (operands[0]));
7992 (define_insn "*rdgsr_sp64"
7993 [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))]
7994 "TARGET_VIS && TARGET_ARCH64"
7996 [(set_attr "type" "gsr")])
7998 (define_insn "rdgsr_v8plus"
7999 [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))
8000 (clobber (match_scratch:SI 1 "=&h"))]
8001 "TARGET_VIS && ! TARGET_ARCH64"
8003 return "rd\t%%gsr, %1\n\tsrlx\t%1, 32, %H0\n\tmov %1, %L0";
8005 [(set_attr "type" "multi")])
8007 ;; Using faligndata only makes sense after an alignaddr since the choice of
8008 ;; bytes to take out of each operand is dependent on the results of the last
8010 (define_insn "faligndata<V64I:mode>_vis"
8011 [(set (match_operand:V64I 0 "register_operand" "=e")
8012 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
8013 (match_operand:V64I 2 "register_operand" "e")]
8015 (use (reg:SI GSR_REG))]
8017 "faligndata\t%1, %2, %0"
8018 [(set_attr "type" "fga")
8019 (set_attr "fptype" "double")])
8021 (define_insn "alignaddrsi_vis"
8022 [(set (match_operand:SI 0 "register_operand" "=r")
8023 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8024 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8025 (set (reg:SI GSR_REG)
8026 (ior:SI (and:SI (reg:SI GSR_REG) (const_int -8))
8027 (and:SI (plus:SI (match_dup 1) (match_dup 2))
8030 "alignaddr\t%r1, %r2, %0")
8032 (define_insn "alignaddrdi_vis"
8033 [(set (match_operand:DI 0 "register_operand" "=r")
8034 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8035 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8036 (set (reg:SI GSR_REG)
8037 (ior:SI (and:SI (reg:SI GSR_REG) (const_int -8))
8038 (and:SI (truncate:SI (plus:DI (match_dup 1) (match_dup 2)))
8041 "alignaddr\t%r1, %r2, %0")
8043 (define_insn "alignaddrlsi_vis"
8044 [(set (match_operand:SI 0 "register_operand" "=r")
8045 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8046 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8047 (set (reg:SI GSR_REG)
8048 (ior:SI (and:SI (reg:SI GSR_REG) (const_int -8))
8049 (xor:SI (and:SI (plus:SI (match_dup 1) (match_dup 2))
8053 "alignaddrl\t%r1, %r2, %0")
8055 (define_insn "alignaddrldi_vis"
8056 [(set (match_operand:DI 0 "register_operand" "=r")
8057 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8058 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8059 (set (reg:SI GSR_REG)
8060 (ior:SI (and:SI (reg:SI GSR_REG) (const_int -8))
8061 (xor:SI (and:SI (truncate:SI (plus:DI (match_dup 1)
8066 "alignaddrl\t%r1, %r2, %0")
8068 (define_insn "pdist_vis"
8069 [(set (match_operand:DI 0 "register_operand" "=e")
8070 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8071 (match_operand:V8QI 2 "register_operand" "e")
8072 (match_operand:DI 3 "register_operand" "0")]
8076 [(set_attr "type" "fga")
8077 (set_attr "fptype" "double")])
8079 ;; Edge instructions produce condition codes equivalent to a 'subcc'
8080 ;; with the same operands.
8081 (define_insn "edge8<P:mode>_vis"
8082 [(set (reg:CC_NOOV CC_REG)
8083 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8084 (match_operand:P 2 "register_operand" "rJ"))
8086 (set (match_operand:P 0 "register_operand" "=r")
8087 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8))]
8089 "edge8\t%r1, %r2, %0"
8090 [(set_attr "type" "edge")])
8092 (define_insn "edge8l<P:mode>_vis"
8093 [(set (reg:CC_NOOV CC_REG)
8094 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8095 (match_operand:P 2 "register_operand" "rJ"))
8097 (set (match_operand:P 0 "register_operand" "=r")
8098 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8L))]
8100 "edge8l\t%r1, %r2, %0"
8101 [(set_attr "type" "edge")])
8103 (define_insn "edge16<P:mode>_vis"
8104 [(set (reg:CC_NOOV CC_REG)
8105 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8106 (match_operand:P 2 "register_operand" "rJ"))
8108 (set (match_operand:P 0 "register_operand" "=r")
8109 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16))]
8111 "edge16\t%r1, %r2, %0"
8112 [(set_attr "type" "edge")])
8114 (define_insn "edge16l<P:mode>_vis"
8115 [(set (reg:CC_NOOV CC_REG)
8116 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8117 (match_operand:P 2 "register_operand" "rJ"))
8119 (set (match_operand:P 0 "register_operand" "=r")
8120 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16L))]
8122 "edge16l\t%r1, %r2, %0"
8123 [(set_attr "type" "edge")])
8125 (define_insn "edge32<P:mode>_vis"
8126 [(set (reg:CC_NOOV CC_REG)
8127 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8128 (match_operand:P 2 "register_operand" "rJ"))
8130 (set (match_operand:P 0 "register_operand" "=r")
8131 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32))]
8133 "edge32\t%r1, %r2, %0"
8134 [(set_attr "type" "edge")])
8136 (define_insn "edge32l<P:mode>_vis"
8137 [(set (reg:CC_NOOV CC_REG)
8138 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8139 (match_operand:P 2 "register_operand" "rJ"))
8141 (set (match_operand:P 0 "register_operand" "=r")
8142 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32L))]
8144 "edge32l\t%r1, %r2, %0"
8145 [(set_attr "type" "edge")])
8147 (define_code_iterator gcond [le ne gt eq])
8148 (define_code_attr gcond_name [(le "le") (ne "ne") (gt "gt") (eq "eq")])
8149 (define_mode_iterator GCM [V4HI V2SI])
8150 (define_mode_attr gcm_name [(V4HI "16") (V2SI "32")])
8152 (define_insn "fcmp<gcond_name><gcm_name><P:mode>_vis"
8153 [(set (match_operand:P 0 "register_operand" "=r")
8154 (unspec:P [(gcond:GCM (match_operand:GCM 1 "register_operand" "e")
8155 (match_operand:GCM 2 "register_operand" "e"))]
8158 "fcmp<gcond_name><gcm_name>\t%1, %2, %0"
8159 [(set_attr "type" "fpmul")
8160 (set_attr "fptype" "double")])