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)
69 (UNSPEC_ALIGNADDRL 57)
84 (UNSPECV_PROBE_STACK_RANGE 11)
88 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
89 (define_mode_iterator I [QI HI SI DI])
90 (define_mode_iterator F [SF DF TF])
92 ;; We don't define V1SI because SI should work just fine.
93 (define_mode_iterator V32 [SF V2HI V4QI])
94 (define_mode_iterator V32I [SI V2HI V4QI])
96 (define_mode_iterator V64 [DF V2SI V4HI V8QI])
97 (define_mode_iterator V64I [DI V2SI V4HI V8QI])
99 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
100 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
101 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
102 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
103 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
106 ;; Attribute for cpu type.
107 ;; These must match the values for enum processor_type in sparc.h.
128 (const (symbol_ref "sparc_cpu_attr")))
130 ;; Attribute for the instruction set.
131 ;; At present we only need to distinguish v9/!v9, but for clarity we
132 ;; test TARGET_V8 too.
133 (define_attr "isa" "v7,v8,v9,sparclet"
135 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
136 (symbol_ref "TARGET_V8") (const_string "v8")
137 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
138 (const_string "v7"))))
144 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
152 fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,edge,
155 multi,savew,flushw,iflush,trap"
156 (const_string "ialu"))
158 ;; True if branch/call has empty delay slot and will emit a nop in it
159 (define_attr "empty_delay_slot" "false,true"
160 (symbol_ref "(empty_delay_slot (insn)
161 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
163 (define_attr "branch_type" "none,icc,fcc,reg"
164 (const_string "none"))
166 (define_attr "pic" "false,true"
167 (symbol_ref "(flag_pic != 0 ? PIC_TRUE : PIC_FALSE)"))
169 (define_attr "calls_alloca" "false,true"
170 (symbol_ref "(cfun->calls_alloca != 0
171 ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)"))
173 (define_attr "calls_eh_return" "false,true"
174 (symbol_ref "(crtl->calls_eh_return != 0
175 ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)"))
177 (define_attr "leaf_function" "false,true"
178 (symbol_ref "(current_function_uses_only_leaf_regs != 0
179 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
181 (define_attr "delayed_branch" "false,true"
182 (symbol_ref "(flag_delayed_branch != 0
183 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
185 (define_attr "flat" "false,true"
186 (symbol_ref "(TARGET_FLAT != 0
187 ? FLAT_TRUE : FLAT_FALSE)"))
189 ;; Length (in # of insns).
190 ;; Beware that setting a length greater or equal to 3 for conditional branches
191 ;; has a side-effect (see output_cbranch and output_v9branch).
192 (define_attr "length" ""
193 (cond [(eq_attr "type" "uncond_branch,call")
194 (if_then_else (eq_attr "empty_delay_slot" "true")
197 (eq_attr "type" "sibcall")
198 (if_then_else (eq_attr "leaf_function" "true")
199 (if_then_else (eq_attr "empty_delay_slot" "true")
202 (if_then_else (eq_attr "empty_delay_slot" "true")
205 (eq_attr "branch_type" "icc")
206 (if_then_else (match_operand 0 "noov_compare64_operator" "")
207 (if_then_else (lt (pc) (match_dup 1))
208 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
209 (if_then_else (eq_attr "empty_delay_slot" "true")
212 (if_then_else (eq_attr "empty_delay_slot" "true")
215 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
216 (if_then_else (eq_attr "empty_delay_slot" "true")
219 (if_then_else (eq_attr "empty_delay_slot" "true")
222 (if_then_else (eq_attr "empty_delay_slot" "true")
225 (eq_attr "branch_type" "fcc")
226 (if_then_else (match_operand 0 "fcc0_register_operand" "")
227 (if_then_else (eq_attr "empty_delay_slot" "true")
228 (if_then_else (not (match_test "TARGET_V9"))
231 (if_then_else (not (match_test "TARGET_V9"))
234 (if_then_else (lt (pc) (match_dup 2))
235 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
236 (if_then_else (eq_attr "empty_delay_slot" "true")
239 (if_then_else (eq_attr "empty_delay_slot" "true")
242 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
243 (if_then_else (eq_attr "empty_delay_slot" "true")
246 (if_then_else (eq_attr "empty_delay_slot" "true")
249 (eq_attr "branch_type" "reg")
250 (if_then_else (lt (pc) (match_dup 2))
251 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
252 (if_then_else (eq_attr "empty_delay_slot" "true")
255 (if_then_else (eq_attr "empty_delay_slot" "true")
258 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
259 (if_then_else (eq_attr "empty_delay_slot" "true")
262 (if_then_else (eq_attr "empty_delay_slot" "true")
268 (define_attr "fptype" "single,double"
269 (const_string "single"))
271 ;; UltraSPARC-III integer load type.
272 (define_attr "us3load_type" "2cycle,3cycle"
273 (const_string "2cycle"))
275 (define_asm_attributes
276 [(set_attr "length" "2")
277 (set_attr "type" "multi")])
279 ;; Attributes for instruction and branch scheduling
280 (define_attr "tls_call_delay" "false,true"
281 (symbol_ref "(tls_call_delay (insn)
282 ? TLS_CALL_DELAY_TRUE : TLS_CALL_DELAY_FALSE)"))
284 (define_attr "in_call_delay" "false,true"
285 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
286 (const_string "false")
287 (eq_attr "type" "load,fpload,store,fpstore")
288 (if_then_else (eq_attr "length" "1")
289 (const_string "true")
290 (const_string "false"))]
291 (if_then_else (and (eq_attr "length" "1")
292 (eq_attr "tls_call_delay" "true"))
293 (const_string "true")
294 (const_string "false"))))
296 (define_attr "eligible_for_sibcall_delay" "false,true"
297 (symbol_ref "(eligible_for_sibcall_delay (insn)
298 ? ELIGIBLE_FOR_SIBCALL_DELAY_TRUE
299 : ELIGIBLE_FOR_SIBCALL_DELAY_FALSE)"))
301 (define_attr "eligible_for_return_delay" "false,true"
302 (symbol_ref "(eligible_for_return_delay (insn)
303 ? ELIGIBLE_FOR_RETURN_DELAY_TRUE
304 : ELIGIBLE_FOR_RETURN_DELAY_FALSE)"))
306 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
307 ;; branches. This would allow us to remove the nop always inserted before
308 ;; a floating point branch.
310 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
311 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
312 ;; This is because doing so will add several pipeline stalls to the path
313 ;; that the load/store did not come from. Unfortunately, there is no way
314 ;; to prevent fill_eager_delay_slots from using load/store without completely
315 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
316 ;; because it prevents us from moving back the final store of inner loops.
318 (define_attr "in_branch_delay" "false,true"
319 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
320 (eq_attr "length" "1"))
321 (const_string "true")
322 (const_string "false")))
324 (define_attr "in_uncond_branch_delay" "false,true"
325 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
326 (eq_attr "length" "1"))
327 (const_string "true")
328 (const_string "false")))
330 (define_attr "in_annul_branch_delay" "false,true"
331 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
332 (eq_attr "length" "1"))
333 (const_string "true")
334 (const_string "false")))
336 (define_delay (eq_attr "type" "call")
337 [(eq_attr "in_call_delay" "true") (nil) (nil)])
339 (define_delay (eq_attr "type" "sibcall")
340 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
342 (define_delay (eq_attr "type" "branch")
343 [(eq_attr "in_branch_delay" "true")
344 (nil) (eq_attr "in_annul_branch_delay" "true")])
346 (define_delay (eq_attr "type" "uncond_branch")
347 [(eq_attr "in_uncond_branch_delay" "true")
350 (define_delay (eq_attr "type" "return")
351 [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
354 ;; Include SPARC DFA schedulers
356 (include "cypress.md")
357 (include "supersparc.md")
358 (include "hypersparc.md")
360 (include "sparclet.md")
361 (include "ultra1_2.md")
362 (include "ultra3.md")
363 (include "niagara.md")
364 (include "niagara2.md")
367 ;; Operand and operator predicates and constraints
369 (include "predicates.md")
370 (include "constraints.md")
373 ;; Compare instructions.
375 ;; These are just the DEFINE_INSNs to match the patterns and the
376 ;; DEFINE_SPLITs for some of the scc insns that actually require
377 ;; more than one machine instruction. DEFINE_EXPANDs are further down.
379 ;; The compare DEFINE_INSNs.
381 (define_insn "*cmpsi_insn"
383 (compare:CC (match_operand:SI 0 "register_operand" "r")
384 (match_operand:SI 1 "arith_operand" "rI")))]
387 [(set_attr "type" "compare")])
389 (define_insn "*cmpdi_sp64"
391 (compare:CCX (match_operand:DI 0 "register_operand" "r")
392 (match_operand:DI 1 "arith_operand" "rI")))]
395 [(set_attr "type" "compare")])
397 (define_insn "*cmpsf_fpe"
398 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
399 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
400 (match_operand:SF 2 "register_operand" "f")))]
404 return "fcmpes\t%0, %1, %2";
405 return "fcmpes\t%1, %2";
407 [(set_attr "type" "fpcmp")])
409 (define_insn "*cmpdf_fpe"
410 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
411 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
412 (match_operand:DF 2 "register_operand" "e")))]
416 return "fcmped\t%0, %1, %2";
417 return "fcmped\t%1, %2";
419 [(set_attr "type" "fpcmp")
420 (set_attr "fptype" "double")])
422 (define_insn "*cmptf_fpe"
423 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
424 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
425 (match_operand:TF 2 "register_operand" "e")))]
426 "TARGET_FPU && TARGET_HARD_QUAD"
429 return "fcmpeq\t%0, %1, %2";
430 return "fcmpeq\t%1, %2";
432 [(set_attr "type" "fpcmp")])
434 (define_insn "*cmpsf_fp"
435 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
436 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
437 (match_operand:SF 2 "register_operand" "f")))]
441 return "fcmps\t%0, %1, %2";
442 return "fcmps\t%1, %2";
444 [(set_attr "type" "fpcmp")])
446 (define_insn "*cmpdf_fp"
447 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
448 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
449 (match_operand:DF 2 "register_operand" "e")))]
453 return "fcmpd\t%0, %1, %2";
454 return "fcmpd\t%1, %2";
456 [(set_attr "type" "fpcmp")
457 (set_attr "fptype" "double")])
459 (define_insn "*cmptf_fp"
460 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
461 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
462 (match_operand:TF 2 "register_operand" "e")))]
463 "TARGET_FPU && TARGET_HARD_QUAD"
466 return "fcmpq\t%0, %1, %2";
467 return "fcmpq\t%1, %2";
469 [(set_attr "type" "fpcmp")])
471 ;; Next come the scc insns.
473 (define_expand "cstoresi4"
474 [(use (match_operator 1 "comparison_operator"
475 [(match_operand:SI 2 "compare_operand" "")
476 (match_operand:SI 3 "arith_operand" "")]))
477 (clobber (match_operand:SI 0 "register_operand"))]
480 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
481 operands[2] = force_reg (SImode, operands[2]);
482 if (emit_scc_insn (operands)) DONE; else FAIL;
485 (define_expand "cstoredi4"
486 [(use (match_operator 1 "comparison_operator"
487 [(match_operand:DI 2 "compare_operand" "")
488 (match_operand:DI 3 "arith_operand" "")]))
489 (clobber (match_operand:SI 0 "register_operand"))]
492 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
493 operands[2] = force_reg (DImode, operands[2]);
494 if (emit_scc_insn (operands)) DONE; else FAIL;
497 (define_expand "cstore<F:mode>4"
498 [(use (match_operator 1 "comparison_operator"
499 [(match_operand:F 2 "register_operand" "")
500 (match_operand:F 3 "register_operand" "")]))
501 (clobber (match_operand:SI 0 "register_operand"))]
503 { if (emit_scc_insn (operands)) DONE; else FAIL; })
507 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
508 ;; generate addcc/subcc instructions.
510 (define_expand "seqsi_special"
512 (xor:SI (match_operand:SI 1 "register_operand" "")
513 (match_operand:SI 2 "register_operand" "")))
514 (parallel [(set (match_operand:SI 0 "register_operand" "")
515 (eq:SI (match_dup 3) (const_int 0)))
516 (clobber (reg:CC 100))])]
518 { operands[3] = gen_reg_rtx (SImode); })
520 (define_expand "seqdi_special"
522 (xor:DI (match_operand:DI 1 "register_operand" "")
523 (match_operand:DI 2 "register_operand" "")))
524 (set (match_operand:SI 0 "register_operand" "")
525 (eq:SI (match_dup 3) (const_int 0)))]
527 { operands[3] = gen_reg_rtx (DImode); })
529 (define_expand "snesi_special"
531 (xor:SI (match_operand:SI 1 "register_operand" "")
532 (match_operand:SI 2 "register_operand" "")))
533 (parallel [(set (match_operand:SI 0 "register_operand" "")
534 (ne:SI (match_dup 3) (const_int 0)))
535 (clobber (reg:CC 100))])]
537 { operands[3] = gen_reg_rtx (SImode); })
539 (define_expand "snedi_special"
541 (xor:DI (match_operand:DI 1 "register_operand" "")
542 (match_operand:DI 2 "register_operand" "")))
543 (set (match_operand:SI 0 "register_operand" "")
544 (ne:SI (match_dup 3) (const_int 0)))]
546 { operands[3] = gen_reg_rtx (DImode); })
549 ;; Now the DEFINE_INSNs for the scc cases.
551 ;; The SEQ and SNE patterns are special because they can be done
552 ;; without any branching and do not involve a COMPARE. We want
553 ;; them to always use the splits below so the results can be
556 (define_insn_and_split "*snesi_zero"
557 [(set (match_operand:SI 0 "register_operand" "=r")
558 (ne:SI (match_operand:SI 1 "register_operand" "r")
560 (clobber (reg:CC 100))]
564 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
566 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
568 [(set_attr "length" "2")])
570 (define_insn_and_split "*neg_snesi_zero"
571 [(set (match_operand:SI 0 "register_operand" "=r")
572 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
574 (clobber (reg:CC 100))]
578 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
580 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
582 [(set_attr "length" "2")])
584 (define_insn_and_split "*snesi_zero_extend"
585 [(set (match_operand:DI 0 "register_operand" "=r")
586 (ne:DI (match_operand:SI 1 "register_operand" "r")
588 (clobber (reg:CC 100))]
592 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
595 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
597 (ltu:SI (reg:CC_NOOV 100)
600 [(set_attr "length" "2")])
602 (define_insn_and_split "*snedi_zero"
603 [(set (match_operand:DI 0 "register_operand" "=&r")
604 (ne:DI (match_operand:DI 1 "register_operand" "r")
608 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
609 [(set (match_dup 0) (const_int 0))
610 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
615 [(set_attr "length" "2")])
617 (define_insn_and_split "*neg_snedi_zero"
618 [(set (match_operand:DI 0 "register_operand" "=&r")
619 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
623 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
624 [(set (match_dup 0) (const_int 0))
625 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
630 [(set_attr "length" "2")])
632 (define_insn_and_split "*snedi_zero_trunc"
633 [(set (match_operand:SI 0 "register_operand" "=&r")
634 (ne:SI (match_operand:DI 1 "register_operand" "r")
638 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
639 [(set (match_dup 0) (const_int 0))
640 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
645 [(set_attr "length" "2")])
647 (define_insn_and_split "*seqsi_zero"
648 [(set (match_operand:SI 0 "register_operand" "=r")
649 (eq:SI (match_operand:SI 1 "register_operand" "r")
651 (clobber (reg:CC 100))]
655 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
657 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
659 [(set_attr "length" "2")])
661 (define_insn_and_split "*neg_seqsi_zero"
662 [(set (match_operand:SI 0 "register_operand" "=r")
663 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
665 (clobber (reg:CC 100))]
669 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
671 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
673 [(set_attr "length" "2")])
675 (define_insn_and_split "*seqsi_zero_extend"
676 [(set (match_operand:DI 0 "register_operand" "=r")
677 (eq:DI (match_operand:SI 1 "register_operand" "r")
679 (clobber (reg:CC 100))]
683 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
686 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
688 (ltu:SI (reg:CC_NOOV 100)
691 [(set_attr "length" "2")])
693 (define_insn_and_split "*seqdi_zero"
694 [(set (match_operand:DI 0 "register_operand" "=&r")
695 (eq:DI (match_operand:DI 1 "register_operand" "r")
699 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
700 [(set (match_dup 0) (const_int 0))
701 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
706 [(set_attr "length" "2")])
708 (define_insn_and_split "*neg_seqdi_zero"
709 [(set (match_operand:DI 0 "register_operand" "=&r")
710 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
714 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
715 [(set (match_dup 0) (const_int 0))
716 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
721 [(set_attr "length" "2")])
723 (define_insn_and_split "*seqdi_zero_trunc"
724 [(set (match_operand:SI 0 "register_operand" "=&r")
725 (eq:SI (match_operand:DI 1 "register_operand" "r")
729 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
730 [(set (match_dup 0) (const_int 0))
731 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
736 [(set_attr "length" "2")])
738 ;; We can also do (x + (i == 0)) and related, so put them in.
739 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
742 (define_insn_and_split "*x_plus_i_ne_0"
743 [(set (match_operand:SI 0 "register_operand" "=r")
744 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
746 (match_operand:SI 2 "register_operand" "r")))
747 (clobber (reg:CC 100))]
751 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
753 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
756 [(set_attr "length" "2")])
758 (define_insn_and_split "*x_minus_i_ne_0"
759 [(set (match_operand:SI 0 "register_operand" "=r")
760 (minus:SI (match_operand:SI 2 "register_operand" "r")
761 (ne:SI (match_operand:SI 1 "register_operand" "r")
763 (clobber (reg:CC 100))]
767 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
769 (set (match_dup 0) (minus:SI (match_dup 2)
770 (ltu:SI (reg:CC 100) (const_int 0))))]
772 [(set_attr "length" "2")])
774 (define_insn_and_split "*x_plus_i_eq_0"
775 [(set (match_operand:SI 0 "register_operand" "=r")
776 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
778 (match_operand:SI 2 "register_operand" "r")))
779 (clobber (reg:CC 100))]
783 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
785 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
788 [(set_attr "length" "2")])
790 (define_insn_and_split "*x_minus_i_eq_0"
791 [(set (match_operand:SI 0 "register_operand" "=r")
792 (minus:SI (match_operand:SI 2 "register_operand" "r")
793 (eq:SI (match_operand:SI 1 "register_operand" "r")
795 (clobber (reg:CC 100))]
799 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
801 (set (match_dup 0) (minus:SI (match_dup 2)
802 (geu:SI (reg:CC 100) (const_int 0))))]
804 [(set_attr "length" "2")])
806 ;; We can also do GEU and LTU directly, but these operate after a compare.
807 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
810 (define_insn "*sltu_insn"
811 [(set (match_operand:SI 0 "register_operand" "=r")
812 (ltu:SI (reg:CC 100) (const_int 0)))]
815 [(set_attr "type" "ialuX")])
817 (define_insn "*neg_sltu_insn"
818 [(set (match_operand:SI 0 "register_operand" "=r")
819 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
822 [(set_attr "type" "ialuX")])
824 ;; ??? Combine should canonicalize these next two to the same pattern.
825 (define_insn "*neg_sltu_minus_x"
826 [(set (match_operand:SI 0 "register_operand" "=r")
827 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
828 (match_operand:SI 1 "arith_operand" "rI")))]
831 [(set_attr "type" "ialuX")])
833 (define_insn "*neg_sltu_plus_x"
834 [(set (match_operand:SI 0 "register_operand" "=r")
835 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
836 (match_operand:SI 1 "arith_operand" "rI"))))]
839 [(set_attr "type" "ialuX")])
841 (define_insn "*sgeu_insn"
842 [(set (match_operand:SI 0 "register_operand" "=r")
843 (geu:SI (reg:CC 100) (const_int 0)))]
846 [(set_attr "type" "ialuX")])
848 (define_insn "*neg_sgeu_insn"
849 [(set (match_operand:SI 0 "register_operand" "=r")
850 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
853 [(set_attr "type" "ialuX")])
855 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
856 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
859 (define_insn "*sltu_plus_x"
860 [(set (match_operand:SI 0 "register_operand" "=r")
861 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
862 (match_operand:SI 1 "arith_operand" "rI")))]
865 [(set_attr "type" "ialuX")])
867 (define_insn "*sltu_plus_x_plus_y"
868 [(set (match_operand:SI 0 "register_operand" "=r")
869 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
870 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
871 (match_operand:SI 2 "arith_operand" "rI"))))]
874 [(set_attr "type" "ialuX")])
876 (define_insn "*x_minus_sltu"
877 [(set (match_operand:SI 0 "register_operand" "=r")
878 (minus:SI (match_operand:SI 1 "register_operand" "r")
879 (ltu:SI (reg:CC 100) (const_int 0))))]
882 [(set_attr "type" "ialuX")])
884 ;; ??? Combine should canonicalize these next two to the same pattern.
885 (define_insn "*x_minus_y_minus_sltu"
886 [(set (match_operand:SI 0 "register_operand" "=r")
887 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
888 (match_operand:SI 2 "arith_operand" "rI"))
889 (ltu:SI (reg:CC 100) (const_int 0))))]
892 [(set_attr "type" "ialuX")])
894 (define_insn "*x_minus_sltu_plus_y"
895 [(set (match_operand:SI 0 "register_operand" "=r")
896 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
897 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
898 (match_operand:SI 2 "arith_operand" "rI"))))]
901 [(set_attr "type" "ialuX")])
903 (define_insn "*sgeu_plus_x"
904 [(set (match_operand:SI 0 "register_operand" "=r")
905 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
906 (match_operand:SI 1 "register_operand" "r")))]
909 [(set_attr "type" "ialuX")])
911 (define_insn "*x_minus_sgeu"
912 [(set (match_operand:SI 0 "register_operand" "=r")
913 (minus:SI (match_operand:SI 1 "register_operand" "r")
914 (geu:SI (reg:CC 100) (const_int 0))))]
917 [(set_attr "type" "ialuX")])
920 [(set (match_operand:SI 0 "register_operand" "")
921 (match_operator:SI 2 "noov_compare_operator"
922 [(match_operand 1 "icc_or_fcc_register_operand" "")
925 && REGNO (operands[1]) == SPARC_ICC_REG
926 && (GET_MODE (operands[1]) == CCXmode
927 /* 32-bit LTU/GEU are better implemented using addx/subx. */
928 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
929 [(set (match_dup 0) (const_int 0))
931 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
937 ;; These control RTL generation for conditional jump insns
939 (define_expand "cbranchcc4"
941 (if_then_else (match_operator 0 "comparison_operator"
942 [(match_operand 1 "compare_operand" "")
943 (match_operand 2 "const_zero_operand" "")])
944 (label_ref (match_operand 3 "" ""))
949 (define_expand "cbranchsi4"
950 [(use (match_operator 0 "comparison_operator"
951 [(match_operand:SI 1 "compare_operand" "")
952 (match_operand:SI 2 "arith_operand" "")]))
953 (use (match_operand 3 ""))]
956 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
957 operands[1] = force_reg (SImode, operands[1]);
958 emit_conditional_branch_insn (operands);
962 (define_expand "cbranchdi4"
963 [(use (match_operator 0 "comparison_operator"
964 [(match_operand:DI 1 "compare_operand" "")
965 (match_operand:DI 2 "arith_operand" "")]))
966 (use (match_operand 3 ""))]
969 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
970 operands[1] = force_reg (DImode, operands[1]);
971 emit_conditional_branch_insn (operands);
975 (define_expand "cbranch<F:mode>4"
976 [(use (match_operator 0 "comparison_operator"
977 [(match_operand:F 1 "register_operand" "")
978 (match_operand:F 2 "register_operand" "")]))
979 (use (match_operand 3 ""))]
981 { emit_conditional_branch_insn (operands); DONE; })
984 ;; Now match both normal and inverted jump.
986 ;; XXX fpcmp nop braindamage
987 (define_insn "*normal_branch"
989 (if_then_else (match_operator 0 "noov_compare_operator"
990 [(reg 100) (const_int 0)])
991 (label_ref (match_operand 1 "" ""))
995 return output_cbranch (operands[0], operands[1], 1, 0,
996 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
999 [(set_attr "type" "branch")
1000 (set_attr "branch_type" "icc")])
1002 ;; XXX fpcmp nop braindamage
1003 (define_insn "*inverted_branch"
1005 (if_then_else (match_operator 0 "noov_compare_operator"
1006 [(reg 100) (const_int 0)])
1008 (label_ref (match_operand 1 "" ""))))]
1011 return output_cbranch (operands[0], operands[1], 1, 1,
1012 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1015 [(set_attr "type" "branch")
1016 (set_attr "branch_type" "icc")])
1018 ;; XXX fpcmp nop braindamage
1019 (define_insn "*normal_fp_branch"
1021 (if_then_else (match_operator 1 "comparison_operator"
1022 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1024 (label_ref (match_operand 2 "" ""))
1028 return output_cbranch (operands[1], operands[2], 2, 0,
1029 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1032 [(set_attr "type" "branch")
1033 (set_attr "branch_type" "fcc")])
1035 ;; XXX fpcmp nop braindamage
1036 (define_insn "*inverted_fp_branch"
1038 (if_then_else (match_operator 1 "comparison_operator"
1039 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1042 (label_ref (match_operand 2 "" ""))))]
1045 return output_cbranch (operands[1], operands[2], 2, 1,
1046 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1049 [(set_attr "type" "branch")
1050 (set_attr "branch_type" "fcc")])
1052 ;; XXX fpcmp nop braindamage
1053 (define_insn "*normal_fpe_branch"
1055 (if_then_else (match_operator 1 "comparison_operator"
1056 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1058 (label_ref (match_operand 2 "" ""))
1062 return output_cbranch (operands[1], operands[2], 2, 0,
1063 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1066 [(set_attr "type" "branch")
1067 (set_attr "branch_type" "fcc")])
1069 ;; XXX fpcmp nop braindamage
1070 (define_insn "*inverted_fpe_branch"
1072 (if_then_else (match_operator 1 "comparison_operator"
1073 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1076 (label_ref (match_operand 2 "" ""))))]
1079 return output_cbranch (operands[1], operands[2], 2, 1,
1080 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1083 [(set_attr "type" "branch")
1084 (set_attr "branch_type" "fcc")])
1086 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1087 ;; in the architecture.
1089 ;; There are no 32 bit brreg insns.
1092 (define_insn "*normal_int_branch_sp64"
1094 (if_then_else (match_operator 0 "v9_register_compare_operator"
1095 [(match_operand:DI 1 "register_operand" "r")
1097 (label_ref (match_operand 2 "" ""))
1101 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1102 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1105 [(set_attr "type" "branch")
1106 (set_attr "branch_type" "reg")])
1109 (define_insn "*inverted_int_branch_sp64"
1111 (if_then_else (match_operator 0 "v9_register_compare_operator"
1112 [(match_operand:DI 1 "register_operand" "r")
1115 (label_ref (match_operand 2 "" ""))))]
1118 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1119 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1122 [(set_attr "type" "branch")
1123 (set_attr "branch_type" "reg")])
1126 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1127 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1128 ;; that adds the PC value at the call point to register #(operand 3).
1130 (define_insn "load_pcrel_sym<P:mode>"
1131 [(set (match_operand:P 0 "register_operand" "=r")
1132 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1133 (match_operand:P 2 "call_address_operand" "")
1134 (match_operand:P 3 "const_int_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1135 (clobber (reg:P 15))]
1136 "REGNO (operands[0]) == INTVAL (operands[3])"
1138 if (flag_delayed_branch)
1139 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1141 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1143 [(set (attr "type") (const_string "multi"))
1144 (set (attr "length")
1145 (if_then_else (eq_attr "delayed_branch" "true")
1150 ;; Integer move instructions
1152 (define_expand "movqi"
1153 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1154 (match_operand:QI 1 "general_operand" ""))]
1157 if (sparc_expand_move (QImode, operands))
1161 (define_insn "*movqi_insn"
1162 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1163 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1164 "(register_operand (operands[0], QImode)
1165 || register_or_zero_operand (operands[1], QImode))"
1170 [(set_attr "type" "*,load,store")
1171 (set_attr "us3load_type" "*,3cycle,*")])
1173 (define_expand "movhi"
1174 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1175 (match_operand:HI 1 "general_operand" ""))]
1178 if (sparc_expand_move (HImode, operands))
1182 (define_insn "*movhi_insn"
1183 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1184 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1185 "(register_operand (operands[0], HImode)
1186 || register_or_zero_operand (operands[1], HImode))"
1189 sethi\t%%hi(%a1), %0
1192 [(set_attr "type" "*,*,load,store")
1193 (set_attr "us3load_type" "*,*,3cycle,*")])
1195 ;; We always work with constants here.
1196 (define_insn "*movhi_lo_sum"
1197 [(set (match_operand:HI 0 "register_operand" "=r")
1198 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1199 (match_operand:HI 2 "small_int_operand" "I")))]
1203 (define_expand "movsi"
1204 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1205 (match_operand:SI 1 "general_operand" ""))]
1208 if (sparc_expand_move (SImode, operands))
1212 (define_insn "*movsi_insn"
1213 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d")
1214 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,f,m,f,J"))]
1215 "(register_operand (operands[0], SImode)
1216 || register_or_zero_operand (operands[1], SImode))"
1219 sethi\t%%hi(%a1), %0
1226 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")])
1228 (define_insn "*movsi_lo_sum"
1229 [(set (match_operand:SI 0 "register_operand" "=r")
1230 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1231 (match_operand:SI 2 "immediate_operand" "in")))]
1233 "or\t%1, %%lo(%a2), %0")
1235 (define_insn "*movsi_high"
1236 [(set (match_operand:SI 0 "register_operand" "=r")
1237 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1239 "sethi\t%%hi(%a1), %0")
1241 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1242 ;; so that CSE won't optimize the address computation away.
1243 (define_insn "movsi_lo_sum_pic"
1244 [(set (match_operand:SI 0 "register_operand" "=r")
1245 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1246 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1249 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1250 return "xor\t%1, %%gdop_lox10(%a2), %0";
1252 return "or\t%1, %%lo(%a2), %0";
1256 (define_insn "movsi_high_pic"
1257 [(set (match_operand:SI 0 "register_operand" "=r")
1258 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1259 "flag_pic && check_pic (1)"
1261 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1262 return "sethi\t%%gdop_hix22(%a1), %0";
1264 return "sethi\t%%hi(%a1), %0";
1268 (define_insn "movsi_pic_gotdata_op"
1269 [(set (match_operand:SI 0 "register_operand" "=r")
1270 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1271 (match_operand:SI 2 "register_operand" "r")
1272 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1273 "flag_pic && check_pic (1)"
1275 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1276 return "ld\t[%1 + %2], %0, %%gdop(%a3)";
1278 return "ld\t[%1 + %2], %0";
1281 [(set_attr "type" "load")])
1283 (define_expand "movsi_pic_label_ref"
1284 [(set (match_dup 3) (high:SI
1285 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1286 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1287 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1288 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1289 (set (match_operand:SI 0 "register_operand" "=r")
1290 (minus:SI (match_dup 5) (match_dup 4)))]
1293 crtl->uses_pic_offset_table = 1;
1294 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1295 if (!can_create_pseudo_p ())
1297 operands[3] = operands[0];
1298 operands[4] = operands[0];
1302 operands[3] = gen_reg_rtx (SImode);
1303 operands[4] = gen_reg_rtx (SImode);
1305 operands[5] = pic_offset_table_rtx;
1308 (define_insn "*movsi_high_pic_label_ref"
1309 [(set (match_operand:SI 0 "register_operand" "=r")
1311 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1312 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1314 "sethi\t%%hi(%a2-(%a1-.)), %0")
1316 (define_insn "*movsi_lo_sum_pic_label_ref"
1317 [(set (match_operand:SI 0 "register_operand" "=r")
1318 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1319 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1320 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1322 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1324 ;; Set up the PIC register for VxWorks.
1326 (define_expand "vxworks_load_got"
1328 (high:SI (match_dup 1)))
1330 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1332 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1333 "TARGET_VXWORKS_RTP"
1335 operands[0] = pic_offset_table_rtx;
1336 operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1337 operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1340 (define_expand "movdi"
1341 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1342 (match_operand:DI 1 "general_operand" ""))]
1345 if (sparc_expand_move (DImode, operands))
1349 ;; Be careful, fmovd does not exist when !v9.
1350 ;; We match MEM moves directly when we have correct even
1351 ;; numbered registers, but fall into splits otherwise.
1352 ;; The constraint ordering here is really important to
1353 ;; avoid insane problems in reload, especially for patterns
1356 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1357 ;; (const_int -5016)))
1361 (define_insn "*movdi_insn_sp32"
1362 [(set (match_operand:DI 0 "nonimmediate_operand"
1363 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1364 (match_operand:DI 1 "input_operand"
1365 " J,U,T,r,o,i,r, f, T, o, f, f"))]
1367 && (register_operand (operands[0], DImode)
1368 || register_or_zero_operand (operands[1], DImode))"
1382 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1383 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1385 (define_insn "*movdi_insn_sp32_v9"
1386 [(set (match_operand:DI 0 "nonimmediate_operand"
1387 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1388 (match_operand:DI 1 "input_operand"
1389 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1392 && (register_operand (operands[0], DImode)
1393 || register_or_zero_operand (operands[1], DImode))"
1410 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
1411 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
1412 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
1414 (define_insn "*movdi_insn_sp64"
1415 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b")
1416 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,e,W,e,J"))]
1418 && (register_operand (operands[0], DImode)
1419 || register_or_zero_operand (operands[1], DImode))"
1422 sethi\t%%hi(%a1), %0
1429 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")
1430 (set_attr "fptype" "*,*,*,*,double,*,*,double")])
1432 (define_expand "movdi_pic_label_ref"
1433 [(set (match_dup 3) (high:DI
1434 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1435 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1436 (set (match_dup 4) (lo_sum:DI (match_dup 3)
1437 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1438 (set (match_operand:DI 0 "register_operand" "=r")
1439 (minus:DI (match_dup 5) (match_dup 4)))]
1440 "TARGET_ARCH64 && flag_pic"
1442 crtl->uses_pic_offset_table = 1;
1443 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1444 if (!can_create_pseudo_p ())
1446 operands[3] = operands[0];
1447 operands[4] = operands[0];
1451 operands[3] = gen_reg_rtx (DImode);
1452 operands[4] = gen_reg_rtx (DImode);
1454 operands[5] = pic_offset_table_rtx;
1457 (define_insn "*movdi_high_pic_label_ref"
1458 [(set (match_operand:DI 0 "register_operand" "=r")
1460 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1461 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1462 "TARGET_ARCH64 && flag_pic"
1463 "sethi\t%%hi(%a2-(%a1-.)), %0")
1465 (define_insn "*movdi_lo_sum_pic_label_ref"
1466 [(set (match_operand:DI 0 "register_operand" "=r")
1467 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1468 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
1469 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1470 "TARGET_ARCH64 && flag_pic"
1471 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1473 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
1474 ;; in sparc.c to see what is going on here... PIC stuff comes first.
1476 (define_insn "movdi_lo_sum_pic"
1477 [(set (match_operand:DI 0 "register_operand" "=r")
1478 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1479 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1480 "TARGET_ARCH64 && flag_pic"
1482 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1483 return "xor\t%1, %%gdop_lox10(%a2), %0";
1485 return "or\t%1, %%lo(%a2), %0";
1489 (define_insn "movdi_high_pic"
1490 [(set (match_operand:DI 0 "register_operand" "=r")
1491 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1492 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1494 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1495 return "sethi\t%%gdop_hix22(%a1), %0";
1497 return "sethi\t%%hi(%a1), %0";
1501 (define_insn "movdi_pic_gotdata_op"
1502 [(set (match_operand:DI 0 "register_operand" "=r")
1503 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1504 (match_operand:DI 2 "register_operand" "r")
1505 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1506 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1508 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1509 return "ldx\t[%1 + %2], %0, %%gdop(%a3)";
1511 return "ldx\t[%1 + %2], %0";
1514 [(set_attr "type" "load")])
1516 (define_insn "*sethi_di_medlow_embmedany_pic"
1517 [(set (match_operand:DI 0 "register_operand" "=r")
1518 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
1519 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
1520 "sethi\t%%hi(%a1), %0")
1522 (define_insn "*sethi_di_medlow"
1523 [(set (match_operand:DI 0 "register_operand" "=r")
1524 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
1525 "TARGET_CM_MEDLOW && check_pic (1)"
1526 "sethi\t%%hi(%a1), %0")
1528 (define_insn "*losum_di_medlow"
1529 [(set (match_operand:DI 0 "register_operand" "=r")
1530 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1531 (match_operand:DI 2 "symbolic_operand" "")))]
1533 "or\t%1, %%lo(%a2), %0")
1535 (define_insn "seth44"
1536 [(set (match_operand:DI 0 "register_operand" "=r")
1537 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
1539 "sethi\t%%h44(%a1), %0")
1541 (define_insn "setm44"
1542 [(set (match_operand:DI 0 "register_operand" "=r")
1543 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1544 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
1546 "or\t%1, %%m44(%a2), %0")
1548 (define_insn "setl44"
1549 [(set (match_operand:DI 0 "register_operand" "=r")
1550 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1551 (match_operand:DI 2 "symbolic_operand" "")))]
1553 "or\t%1, %%l44(%a2), %0")
1555 (define_insn "sethh"
1556 [(set (match_operand:DI 0 "register_operand" "=r")
1557 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
1559 "sethi\t%%hh(%a1), %0")
1561 (define_insn "setlm"
1562 [(set (match_operand:DI 0 "register_operand" "=r")
1563 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
1565 "sethi\t%%lm(%a1), %0")
1567 (define_insn "sethm"
1568 [(set (match_operand:DI 0 "register_operand" "=r")
1569 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1570 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
1572 "or\t%1, %%hm(%a2), %0")
1574 (define_insn "setlo"
1575 [(set (match_operand:DI 0 "register_operand" "=r")
1576 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1577 (match_operand:DI 2 "symbolic_operand" "")))]
1579 "or\t%1, %%lo(%a2), %0")
1581 (define_insn "embmedany_sethi"
1582 [(set (match_operand:DI 0 "register_operand" "=r")
1583 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
1584 "TARGET_CM_EMBMEDANY && check_pic (1)"
1585 "sethi\t%%hi(%a1), %0")
1587 (define_insn "embmedany_losum"
1588 [(set (match_operand:DI 0 "register_operand" "=r")
1589 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1590 (match_operand:DI 2 "data_segment_operand" "")))]
1591 "TARGET_CM_EMBMEDANY"
1592 "add\t%1, %%lo(%a2), %0")
1594 (define_insn "embmedany_brsum"
1595 [(set (match_operand:DI 0 "register_operand" "=r")
1596 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
1597 "TARGET_CM_EMBMEDANY"
1600 (define_insn "embmedany_textuhi"
1601 [(set (match_operand:DI 0 "register_operand" "=r")
1602 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
1603 "TARGET_CM_EMBMEDANY && check_pic (1)"
1604 "sethi\t%%uhi(%a1), %0")
1606 (define_insn "embmedany_texthi"
1607 [(set (match_operand:DI 0 "register_operand" "=r")
1608 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
1609 "TARGET_CM_EMBMEDANY && check_pic (1)"
1610 "sethi\t%%hi(%a1), %0")
1612 (define_insn "embmedany_textulo"
1613 [(set (match_operand:DI 0 "register_operand" "=r")
1614 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1615 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
1616 "TARGET_CM_EMBMEDANY"
1617 "or\t%1, %%ulo(%a2), %0")
1619 (define_insn "embmedany_textlo"
1620 [(set (match_operand:DI 0 "register_operand" "=r")
1621 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1622 (match_operand:DI 2 "text_segment_operand" "")))]
1623 "TARGET_CM_EMBMEDANY"
1624 "or\t%1, %%lo(%a2), %0")
1626 ;; Now some patterns to help reload out a bit.
1627 (define_expand "reload_indi"
1628 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1629 (match_operand:DI 1 "immediate_operand" "")
1630 (match_operand:TI 2 "register_operand" "=&r")])]
1632 || TARGET_CM_EMBMEDANY)
1635 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1639 (define_expand "reload_outdi"
1640 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1641 (match_operand:DI 1 "immediate_operand" "")
1642 (match_operand:TI 2 "register_operand" "=&r")])]
1644 || TARGET_CM_EMBMEDANY)
1647 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1651 ;; Split up putting CONSTs and REGs into DI regs when !arch64
1653 [(set (match_operand:DI 0 "register_operand" "")
1654 (match_operand:DI 1 "const_int_operand" ""))]
1655 "! TARGET_ARCH64 && reload_completed"
1656 [(clobber (const_int 0))]
1658 #if HOST_BITS_PER_WIDE_INT == 32
1659 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1660 (INTVAL (operands[1]) < 0) ?
1663 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1666 unsigned int low, high;
1668 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
1669 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
1670 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
1672 /* Slick... but this trick loses if this subreg constant part
1673 can be done in one insn. */
1675 && ! SPARC_SETHI32_P (high)
1676 && ! SPARC_SIMM13_P (high))
1677 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1678 gen_highpart (SImode, operands[0])));
1680 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
1686 [(set (match_operand:DI 0 "register_operand" "")
1687 (match_operand:DI 1 "const_double_operand" ""))]
1691 && ((GET_CODE (operands[0]) == REG
1692 && REGNO (operands[0]) < 32)
1693 || (GET_CODE (operands[0]) == SUBREG
1694 && GET_CODE (SUBREG_REG (operands[0])) == REG
1695 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1696 [(clobber (const_int 0))]
1698 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1699 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
1701 /* Slick... but this trick loses if this subreg constant part
1702 can be done in one insn. */
1703 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
1704 && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
1705 && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
1707 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1708 gen_highpart (SImode, operands[0])));
1712 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1713 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
1719 [(set (match_operand:DI 0 "register_operand" "")
1720 (match_operand:DI 1 "register_operand" ""))]
1724 && ((GET_CODE (operands[0]) == REG
1725 && REGNO (operands[0]) < 32)
1726 || (GET_CODE (operands[0]) == SUBREG
1727 && GET_CODE (SUBREG_REG (operands[0])) == REG
1728 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1729 [(clobber (const_int 0))]
1731 rtx set_dest = operands[0];
1732 rtx set_src = operands[1];
1736 dest1 = gen_highpart (SImode, set_dest);
1737 dest2 = gen_lowpart (SImode, set_dest);
1738 src1 = gen_highpart (SImode, set_src);
1739 src2 = gen_lowpart (SImode, set_src);
1741 /* Now emit using the real source and destination we found, swapping
1742 the order if we detect overlap. */
1743 if (reg_overlap_mentioned_p (dest1, src2))
1745 emit_insn (gen_movsi (dest2, src2));
1746 emit_insn (gen_movsi (dest1, src1));
1750 emit_insn (gen_movsi (dest1, src1));
1751 emit_insn (gen_movsi (dest2, src2));
1756 ;; Now handle the cases of memory moves from/to non-even
1757 ;; DI mode register pairs.
1759 [(set (match_operand:DI 0 "register_operand" "")
1760 (match_operand:DI 1 "memory_operand" ""))]
1763 && sparc_splitdi_legitimate (operands[0], operands[1]))"
1764 [(clobber (const_int 0))]
1766 rtx word0 = adjust_address (operands[1], SImode, 0);
1767 rtx word1 = adjust_address (operands[1], SImode, 4);
1768 rtx high_part = gen_highpart (SImode, operands[0]);
1769 rtx low_part = gen_lowpart (SImode, operands[0]);
1771 if (reg_overlap_mentioned_p (high_part, word1))
1773 emit_insn (gen_movsi (low_part, word1));
1774 emit_insn (gen_movsi (high_part, word0));
1778 emit_insn (gen_movsi (high_part, word0));
1779 emit_insn (gen_movsi (low_part, word1));
1785 [(set (match_operand:DI 0 "memory_operand" "")
1786 (match_operand:DI 1 "register_operand" ""))]
1789 && sparc_splitdi_legitimate (operands[1], operands[0]))"
1790 [(clobber (const_int 0))]
1792 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
1793 gen_highpart (SImode, operands[1])));
1794 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
1795 gen_lowpart (SImode, operands[1])));
1800 [(set (match_operand:DI 0 "memory_operand" "")
1801 (match_operand:DI 1 "const_zero_operand" ""))]
1805 && ! mem_min_alignment (operands[0], 8)))
1806 && offsettable_memref_p (operands[0])"
1807 [(clobber (const_int 0))]
1809 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
1810 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
1815 ;; Floating point and vector move instructions
1817 ;; Yes, you guessed it right, the former movsf expander.
1818 (define_expand "mov<V32:mode>"
1819 [(set (match_operand:V32 0 "nonimmediate_operand" "")
1820 (match_operand:V32 1 "general_operand" ""))]
1821 "<V32:MODE>mode == SFmode || TARGET_VIS"
1823 if (sparc_expand_move (<V32:MODE>mode, operands))
1827 (define_insn "*movsf_insn"
1828 [(set (match_operand:V32 0 "nonimmediate_operand" "=d,f,*r,*r,*r,f,*r,m,m")
1829 (match_operand:V32 1 "input_operand" "GY,f,*rRY,Q,S,m,m,f,*rGY"))]
1831 && (register_operand (operands[0], <V32:MODE>mode)
1832 || register_or_zero_operand (operands[1], <V32:MODE>mode))"
1834 if (GET_CODE (operands[1]) == CONST_DOUBLE
1835 && (which_alternative == 2
1836 || which_alternative == 3
1837 || which_alternative == 4))
1842 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1843 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1844 operands[1] = GEN_INT (i);
1847 switch (which_alternative)
1850 return "fzeros\t%0";
1852 return "fmovs\t%1, %0";
1854 return "mov\t%1, %0";
1856 return "sethi\t%%hi(%a1), %0";
1861 return "ld\t%1, %0";
1864 return "st\t%r1, %0";
1869 [(set_attr "type" "fga,fpmove,*,*,*,fpload,load,fpstore,store")])
1871 ;; Exactly the same as above, except that all `f' cases are deleted.
1872 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1875 (define_insn "*movsf_insn_no_fpu"
1876 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
1877 (match_operand:SF 1 "input_operand" "rR,Q,S,m,rG"))]
1879 && (register_operand (operands[0], SFmode)
1880 || register_or_zero_operand (operands[1], SFmode))"
1882 if (GET_CODE (operands[1]) == CONST_DOUBLE
1883 && (which_alternative == 0
1884 || which_alternative == 1
1885 || which_alternative == 2))
1890 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1891 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1892 operands[1] = GEN_INT (i);
1895 switch (which_alternative)
1898 return "mov\t%1, %0";
1900 return "sethi\t%%hi(%a1), %0";
1904 return "ld\t%1, %0";
1906 return "st\t%r1, %0";
1911 [(set_attr "type" "*,*,*,load,store")])
1913 ;; The following 3 patterns build SFmode constants in integer registers.
1915 (define_insn "*movsf_lo_sum"
1916 [(set (match_operand:SF 0 "register_operand" "=r")
1917 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
1918 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
1924 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
1925 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1926 operands[2] = GEN_INT (i);
1927 return "or\t%1, %%lo(%a2), %0";
1930 (define_insn "*movsf_high"
1931 [(set (match_operand:SF 0 "register_operand" "=r")
1932 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
1938 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1939 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1940 operands[1] = GEN_INT (i);
1941 return "sethi\t%%hi(%1), %0";
1945 [(set (match_operand:SF 0 "register_operand" "")
1946 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
1947 "REG_P (operands[0]) && REGNO (operands[0]) < 32"
1948 [(set (match_dup 0) (high:SF (match_dup 1)))
1949 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
1951 ;; Yes, you again guessed it right, the former movdf expander.
1952 (define_expand "mov<V64:mode>"
1953 [(set (match_operand:V64 0 "nonimmediate_operand" "")
1954 (match_operand:V64 1 "general_operand" ""))]
1955 "<V64:MODE>mode == DFmode || TARGET_VIS"
1957 if (sparc_expand_move (<V64:MODE>mode, operands))
1961 ;; Be careful, fmovd does not exist when !v9.
1962 (define_insn "*movdf_insn_sp32"
1963 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
1964 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
1967 && (register_operand (operands[0], DFmode)
1968 || register_or_zero_operand (operands[1], DFmode))"
1980 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
1981 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
1983 (define_insn "*movdf_insn_sp32_no_fpu"
1984 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
1985 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
1988 && (register_operand (operands[0], DFmode)
1989 || register_or_zero_operand (operands[1], DFmode))"
1996 [(set_attr "type" "load,store,*,*,*")
1997 (set_attr "length" "*,*,2,2,2")])
1999 ;; We have available v9 double floats but not 64-bit integer registers.
2000 (define_insn "*movdf_insn_sp32_v9"
2001 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o")
2002 (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYDF,*rGYf"))]
2006 && (register_operand (operands[0], <V64:MODE>mode)
2007 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2019 [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
2020 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2021 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2023 (define_insn "*movdf_insn_sp32_v9_no_fpu"
2024 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2025 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2029 && (register_operand (operands[0], DFmode)
2030 || register_or_zero_operand (operands[1], DFmode))"
2037 [(set_attr "type" "load,store,store,*,*")
2038 (set_attr "length" "*,*,*,2,2")])
2040 ;; We have available both v9 double floats and 64-bit integer registers.
2041 (define_insn "*movdf_insn_sp64"
2042 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r")
2043 (match_operand:V64 1 "input_operand" "GY,e,W#F,e,*rGY,m,*rGY,DF"))]
2046 && (register_operand (operands[0], <V64:MODE>mode)
2047 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2057 [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
2058 (set_attr "length" "*,*,*,*,*,*,*,2")
2059 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
2061 (define_insn "*movdf_insn_sp64_no_fpu"
2062 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2063 (match_operand:DF 1 "input_operand" "r,m,rG"))]
2066 && (register_operand (operands[0], DFmode)
2067 || register_or_zero_operand (operands[1], DFmode))"
2072 [(set_attr "type" "*,load,store")])
2074 ;; This pattern builds V64mode constants in integer registers.
2076 [(set (match_operand:V64 0 "register_operand" "")
2077 (match_operand:V64 1 "const_double_or_vector_operand" ""))]
2079 && (GET_CODE (operands[0]) == REG
2080 && REGNO (operands[0]) < 32)
2081 && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2082 && reload_completed"
2083 [(clobber (const_int 0))]
2085 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2089 #if HOST_BITS_PER_WIDE_INT == 32
2092 enum machine_mode mode = GET_MODE (operands[1]);
2093 rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2094 emit_insn (gen_movdi (operands[0], tem));
2099 enum machine_mode mode = GET_MODE (operands[1]);
2100 rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2101 rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2103 gcc_assert (GET_CODE (hi) == CONST_INT);
2104 gcc_assert (GET_CODE (lo) == CONST_INT);
2106 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2108 /* Slick... but this trick loses if this subreg constant part
2109 can be done in one insn. */
2111 && ! SPARC_SETHI32_P (INTVAL (hi))
2112 && ! SPARC_SIMM13_P (INTVAL (hi)))
2114 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2115 gen_highpart (SImode, operands[0])));
2119 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2125 ;; Ok, now the splits to handle all the multi insn and
2126 ;; mis-aligned memory address cases.
2127 ;; In these splits please take note that we must be
2128 ;; careful when V9 but not ARCH64 because the integer
2129 ;; register DFmode cases must be handled.
2131 [(set (match_operand:V64 0 "register_operand" "")
2132 (match_operand:V64 1 "register_operand" ""))]
2135 && ((GET_CODE (operands[0]) == REG
2136 && REGNO (operands[0]) < 32)
2137 || (GET_CODE (operands[0]) == SUBREG
2138 && GET_CODE (SUBREG_REG (operands[0])) == REG
2139 && REGNO (SUBREG_REG (operands[0])) < 32))))
2140 && reload_completed"
2141 [(clobber (const_int 0))]
2143 rtx set_dest = operands[0];
2144 rtx set_src = operands[1];
2147 enum machine_mode half_mode;
2149 /* We can be expanded for DFmode or integral vector modes. */
2150 if (<V64:MODE>mode == DFmode)
2155 dest1 = gen_highpart (half_mode, set_dest);
2156 dest2 = gen_lowpart (half_mode, set_dest);
2157 src1 = gen_highpart (half_mode, set_src);
2158 src2 = gen_lowpart (half_mode, set_src);
2160 /* Now emit using the real source and destination we found, swapping
2161 the order if we detect overlap. */
2162 if (reg_overlap_mentioned_p (dest1, src2))
2164 emit_move_insn_1 (dest2, src2);
2165 emit_move_insn_1 (dest1, src1);
2169 emit_move_insn_1 (dest1, src1);
2170 emit_move_insn_1 (dest2, src2);
2176 [(set (match_operand:V64 0 "register_operand" "")
2177 (match_operand:V64 1 "memory_operand" ""))]
2180 && (((REGNO (operands[0]) % 2) != 0)
2181 || ! mem_min_alignment (operands[1], 8))
2182 && offsettable_memref_p (operands[1])"
2183 [(clobber (const_int 0))]
2185 enum machine_mode half_mode;
2188 /* We can be expanded for DFmode or integral vector modes. */
2189 if (<V64:MODE>mode == DFmode)
2194 word0 = adjust_address (operands[1], half_mode, 0);
2195 word1 = adjust_address (operands[1], half_mode, 4);
2197 if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
2199 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2200 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2204 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2205 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2211 [(set (match_operand:V64 0 "memory_operand" "")
2212 (match_operand:V64 1 "register_operand" ""))]
2215 && (((REGNO (operands[1]) % 2) != 0)
2216 || ! mem_min_alignment (operands[0], 8))
2217 && offsettable_memref_p (operands[0])"
2218 [(clobber (const_int 0))]
2220 enum machine_mode half_mode;
2223 /* We can be expanded for DFmode or integral vector modes. */
2224 if (<V64:MODE>mode == DFmode)
2229 word0 = adjust_address (operands[0], half_mode, 0);
2230 word1 = adjust_address (operands[0], half_mode, 4);
2232 emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
2233 emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
2238 [(set (match_operand:V64 0 "memory_operand" "")
2239 (match_operand:V64 1 "const_zero_operand" ""))]
2243 && ! mem_min_alignment (operands[0], 8)))
2244 && offsettable_memref_p (operands[0])"
2245 [(clobber (const_int 0))]
2247 enum machine_mode half_mode;
2250 /* We can be expanded for DFmode or integral vector modes. */
2251 if (<V64:MODE>mode == DFmode)
2256 dest1 = adjust_address (operands[0], half_mode, 0);
2257 dest2 = adjust_address (operands[0], half_mode, 4);
2259 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2260 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2265 [(set (match_operand:V64 0 "register_operand" "")
2266 (match_operand:V64 1 "const_zero_operand" ""))]
2269 && ((GET_CODE (operands[0]) == REG
2270 && REGNO (operands[0]) < 32)
2271 || (GET_CODE (operands[0]) == SUBREG
2272 && GET_CODE (SUBREG_REG (operands[0])) == REG
2273 && REGNO (SUBREG_REG (operands[0])) < 32))"
2274 [(clobber (const_int 0))]
2276 enum machine_mode half_mode;
2277 rtx set_dest = operands[0];
2280 /* We can be expanded for DFmode or integral vector modes. */
2281 if (<V64:MODE>mode == DFmode)
2286 dest1 = gen_highpart (half_mode, set_dest);
2287 dest2 = gen_lowpart (half_mode, set_dest);
2288 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2289 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2293 (define_expand "movtf"
2294 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2295 (match_operand:TF 1 "general_operand" ""))]
2298 if (sparc_expand_move (TFmode, operands))
2302 (define_insn "*movtf_insn_sp32"
2303 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2304 (match_operand:TF 1 "input_operand" "G,oe,GeUr,o,roG"))]
2307 && (register_operand (operands[0], TFmode)
2308 || register_or_zero_operand (operands[1], TFmode))"
2310 [(set_attr "length" "4")])
2312 ;; Exactly the same as above, except that all `e' cases are deleted.
2313 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2316 (define_insn "*movtf_insn_sp32_no_fpu"
2317 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2318 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
2321 && (register_operand (operands[0], TFmode)
2322 || register_or_zero_operand (operands[1], TFmode))"
2324 [(set_attr "length" "4")])
2326 (define_insn "*movtf_insn_sp64"
2327 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2328 (match_operand:TF 1 "input_operand" "G,oe,Ger,roG"))]
2331 && ! TARGET_HARD_QUAD
2332 && (register_operand (operands[0], TFmode)
2333 || register_or_zero_operand (operands[1], TFmode))"
2335 [(set_attr "length" "2")])
2337 (define_insn "*movtf_insn_sp64_hq"
2338 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2339 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
2343 && (register_operand (operands[0], TFmode)
2344 || register_or_zero_operand (operands[1], TFmode))"
2352 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2353 (set_attr "length" "2,*,*,*,2,2")])
2355 (define_insn "*movtf_insn_sp64_no_fpu"
2356 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2357 (match_operand:TF 1 "input_operand" "orG,rG"))]
2360 && (register_operand (operands[0], TFmode)
2361 || register_or_zero_operand (operands[1], TFmode))"
2363 [(set_attr "length" "2")])
2365 ;; Now all the splits to handle multi-insn TF mode moves.
2367 [(set (match_operand:TF 0 "register_operand" "")
2368 (match_operand:TF 1 "register_operand" ""))]
2372 && ! TARGET_HARD_QUAD)
2373 || ! fp_register_operand (operands[0], TFmode))"
2374 [(clobber (const_int 0))]
2376 rtx set_dest = operands[0];
2377 rtx set_src = operands[1];
2381 dest1 = gen_df_reg (set_dest, 0);
2382 dest2 = gen_df_reg (set_dest, 1);
2383 src1 = gen_df_reg (set_src, 0);
2384 src2 = gen_df_reg (set_src, 1);
2386 /* Now emit using the real source and destination we found, swapping
2387 the order if we detect overlap. */
2388 if (reg_overlap_mentioned_p (dest1, src2))
2390 emit_insn (gen_movdf (dest2, src2));
2391 emit_insn (gen_movdf (dest1, src1));
2395 emit_insn (gen_movdf (dest1, src1));
2396 emit_insn (gen_movdf (dest2, src2));
2402 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2403 (match_operand:TF 1 "const_zero_operand" ""))]
2405 [(clobber (const_int 0))]
2407 rtx set_dest = operands[0];
2410 switch (GET_CODE (set_dest))
2413 dest1 = gen_df_reg (set_dest, 0);
2414 dest2 = gen_df_reg (set_dest, 1);
2417 dest1 = adjust_address (set_dest, DFmode, 0);
2418 dest2 = adjust_address (set_dest, DFmode, 8);
2424 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2425 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2430 [(set (match_operand:TF 0 "register_operand" "")
2431 (match_operand:TF 1 "memory_operand" ""))]
2433 && offsettable_memref_p (operands[1])
2435 || ! TARGET_HARD_QUAD
2436 || ! fp_register_operand (operands[0], TFmode)))"
2437 [(clobber (const_int 0))]
2439 rtx word0 = adjust_address (operands[1], DFmode, 0);
2440 rtx word1 = adjust_address (operands[1], DFmode, 8);
2441 rtx set_dest, dest1, dest2;
2443 set_dest = operands[0];
2445 dest1 = gen_df_reg (set_dest, 0);
2446 dest2 = gen_df_reg (set_dest, 1);
2448 /* Now output, ordering such that we don't clobber any registers
2449 mentioned in the address. */
2450 if (reg_overlap_mentioned_p (dest1, word1))
2453 emit_insn (gen_movdf (dest2, word1));
2454 emit_insn (gen_movdf (dest1, word0));
2458 emit_insn (gen_movdf (dest1, word0));
2459 emit_insn (gen_movdf (dest2, word1));
2465 [(set (match_operand:TF 0 "memory_operand" "")
2466 (match_operand:TF 1 "register_operand" ""))]
2468 && offsettable_memref_p (operands[0])
2470 || ! TARGET_HARD_QUAD
2471 || ! fp_register_operand (operands[1], TFmode)))"
2472 [(clobber (const_int 0))]
2474 rtx set_src = operands[1];
2476 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2477 gen_df_reg (set_src, 0)));
2478 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2479 gen_df_reg (set_src, 1)));
2484 ;; SPARC-V9 conditional move instructions
2486 ;; We can handle larger constants here for some flavors, but for now we keep
2487 ;; it simple and only allow those constants supported by all flavors.
2488 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2489 ;; 3 contains the constant if one is present, but we handle either for
2490 ;; generality (sparc.c puts a constant in operand 2).
2492 (define_expand "mov<I:mode>cc"
2493 [(set (match_operand:I 0 "register_operand" "")
2494 (if_then_else:I (match_operand 1 "comparison_operator" "")
2495 (match_operand:I 2 "arith10_operand" "")
2496 (match_operand:I 3 "arith10_operand" "")))]
2497 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2499 enum rtx_code code = GET_CODE (operands[1]);
2502 if (GET_MODE (XEXP (operands[1], 0)) == DImode
2506 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2508 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2509 GET_CODE (operands[1]));
2511 if (XEXP (operands[1], 1) == const0_rtx
2512 && GET_CODE (XEXP (operands[1], 0)) == REG
2513 && GET_MODE (XEXP (operands[1], 0)) == DImode
2514 && v9_regcmp_p (code))
2515 cc_reg = XEXP (operands[1], 0);
2517 cc_reg = gen_compare_reg (operands[1]);
2519 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2522 (define_expand "mov<F:mode>cc"
2523 [(set (match_operand:F 0 "register_operand" "")
2524 (if_then_else:F (match_operand 1 "comparison_operator" "")
2525 (match_operand:F 2 "register_operand" "")
2526 (match_operand:F 3 "register_operand" "")))]
2527 "TARGET_V9 && TARGET_FPU"
2529 enum rtx_code code = GET_CODE (operands[1]);
2532 if (GET_MODE (XEXP (operands[1], 0)) == DImode
2536 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2538 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2539 GET_CODE (operands[1]));
2541 if (XEXP (operands[1], 1) == const0_rtx
2542 && GET_CODE (XEXP (operands[1], 0)) == REG
2543 && GET_MODE (XEXP (operands[1], 0)) == DImode
2544 && v9_regcmp_p (code))
2545 cc_reg = XEXP (operands[1], 0);
2547 cc_reg = gen_compare_reg (operands[1]);
2549 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2552 ;; Conditional move define_insns
2554 (define_insn "*mov<I:mode>_cc_v9"
2555 [(set (match_operand:I 0 "register_operand" "=r,r")
2556 (if_then_else:I (match_operator 1 "comparison_operator"
2557 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2559 (match_operand:I 3 "arith11_operand" "rL,0")
2560 (match_operand:I 4 "arith11_operand" "0,rL")))]
2561 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2564 mov%c1\t%x2, %4, %0"
2565 [(set_attr "type" "cmove")])
2567 (define_insn "*mov<I:mode>_cc_reg_sp64"
2568 [(set (match_operand:I 0 "register_operand" "=r,r")
2569 (if_then_else:I (match_operator 1 "v9_register_compare_operator"
2570 [(match_operand:DI 2 "register_operand" "r,r")
2572 (match_operand:I 3 "arith10_operand" "rM,0")
2573 (match_operand:I 4 "arith10_operand" "0,rM")))]
2576 movr%D1\t%2, %r3, %0
2577 movr%d1\t%2, %r4, %0"
2578 [(set_attr "type" "cmove")])
2580 (define_insn "*movsf_cc_v9"
2581 [(set (match_operand:SF 0 "register_operand" "=f,f")
2582 (if_then_else:SF (match_operator 1 "comparison_operator"
2583 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2585 (match_operand:SF 3 "register_operand" "f,0")
2586 (match_operand:SF 4 "register_operand" "0,f")))]
2587 "TARGET_V9 && TARGET_FPU"
2589 fmovs%C1\t%x2, %3, %0
2590 fmovs%c1\t%x2, %4, %0"
2591 [(set_attr "type" "fpcmove")])
2593 (define_insn "*movsf_cc_reg_sp64"
2594 [(set (match_operand:SF 0 "register_operand" "=f,f")
2595 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
2596 [(match_operand:DI 2 "register_operand" "r,r")
2598 (match_operand:SF 3 "register_operand" "f,0")
2599 (match_operand:SF 4 "register_operand" "0,f")))]
2600 "TARGET_ARCH64 && TARGET_FPU"
2602 fmovrs%D1\t%2, %3, %0
2603 fmovrs%d1\t%2, %4, %0"
2604 [(set_attr "type" "fpcrmove")])
2606 ;; Named because invoked by movtf_cc_v9
2607 (define_insn "movdf_cc_v9"
2608 [(set (match_operand:DF 0 "register_operand" "=e,e")
2609 (if_then_else:DF (match_operator 1 "comparison_operator"
2610 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2612 (match_operand:DF 3 "register_operand" "e,0")
2613 (match_operand:DF 4 "register_operand" "0,e")))]
2614 "TARGET_V9 && TARGET_FPU"
2616 fmovd%C1\t%x2, %3, %0
2617 fmovd%c1\t%x2, %4, %0"
2618 [(set_attr "type" "fpcmove")
2619 (set_attr "fptype" "double")])
2621 ;; Named because invoked by movtf_cc_reg_sp64
2622 (define_insn "movdf_cc_reg_sp64"
2623 [(set (match_operand:DF 0 "register_operand" "=e,e")
2624 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
2625 [(match_operand:DI 2 "register_operand" "r,r")
2627 (match_operand:DF 3 "register_operand" "e,0")
2628 (match_operand:DF 4 "register_operand" "0,e")))]
2629 "TARGET_ARCH64 && TARGET_FPU"
2631 fmovrd%D1\t%2, %3, %0
2632 fmovrd%d1\t%2, %4, %0"
2633 [(set_attr "type" "fpcrmove")
2634 (set_attr "fptype" "double")])
2636 (define_insn "*movtf_cc_hq_v9"
2637 [(set (match_operand:TF 0 "register_operand" "=e,e")
2638 (if_then_else:TF (match_operator 1 "comparison_operator"
2639 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2641 (match_operand:TF 3 "register_operand" "e,0")
2642 (match_operand:TF 4 "register_operand" "0,e")))]
2643 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2645 fmovq%C1\t%x2, %3, %0
2646 fmovq%c1\t%x2, %4, %0"
2647 [(set_attr "type" "fpcmove")])
2649 (define_insn "*movtf_cc_reg_hq_sp64"
2650 [(set (match_operand:TF 0 "register_operand" "=e,e")
2651 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2652 [(match_operand:DI 2 "register_operand" "r,r")
2654 (match_operand:TF 3 "register_operand" "e,0")
2655 (match_operand:TF 4 "register_operand" "0,e")))]
2656 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
2658 fmovrq%D1\t%2, %3, %0
2659 fmovrq%d1\t%2, %4, %0"
2660 [(set_attr "type" "fpcrmove")])
2662 (define_insn_and_split "*movtf_cc_v9"
2663 [(set (match_operand:TF 0 "register_operand" "=e,e")
2664 (if_then_else:TF (match_operator 1 "comparison_operator"
2665 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2667 (match_operand:TF 3 "register_operand" "e,0")
2668 (match_operand:TF 4 "register_operand" "0,e")))]
2669 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
2671 "&& reload_completed"
2672 [(clobber (const_int 0))]
2674 rtx set_dest = operands[0];
2675 rtx set_srca = operands[3];
2676 rtx set_srcb = operands[4];
2677 int third = rtx_equal_p (set_dest, set_srca);
2679 rtx srca1, srca2, srcb1, srcb2;
2681 dest1 = gen_df_reg (set_dest, 0);
2682 dest2 = gen_df_reg (set_dest, 1);
2683 srca1 = gen_df_reg (set_srca, 0);
2684 srca2 = gen_df_reg (set_srca, 1);
2685 srcb1 = gen_df_reg (set_srcb, 0);
2686 srcb2 = gen_df_reg (set_srcb, 1);
2688 /* Now emit using the real source and destination we found, swapping
2689 the order if we detect overlap. */
2690 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2691 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2693 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2694 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2698 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2699 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2703 [(set_attr "length" "2")])
2705 (define_insn_and_split "*movtf_cc_reg_sp64"
2706 [(set (match_operand:TF 0 "register_operand" "=e,e")
2707 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2708 [(match_operand:DI 2 "register_operand" "r,r")
2710 (match_operand:TF 3 "register_operand" "e,0")
2711 (match_operand:TF 4 "register_operand" "0,e")))]
2712 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
2714 "&& reload_completed"
2715 [(clobber (const_int 0))]
2717 rtx set_dest = operands[0];
2718 rtx set_srca = operands[3];
2719 rtx set_srcb = operands[4];
2720 int third = rtx_equal_p (set_dest, set_srca);
2722 rtx srca1, srca2, srcb1, srcb2;
2724 dest1 = gen_df_reg (set_dest, 0);
2725 dest2 = gen_df_reg (set_dest, 1);
2726 srca1 = gen_df_reg (set_srca, 0);
2727 srca2 = gen_df_reg (set_srca, 1);
2728 srcb1 = gen_df_reg (set_srcb, 0);
2729 srcb2 = gen_df_reg (set_srcb, 1);
2731 /* Now emit using the real source and destination we found, swapping
2732 the order if we detect overlap. */
2733 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2734 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2736 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2737 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2741 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2742 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2746 [(set_attr "length" "2")])
2749 ;; Zero-extension instructions
2751 ;; These patterns originally accepted general_operands, however, slightly
2752 ;; better code is generated by only accepting register_operands, and then
2753 ;; letting combine generate the ldu[hb] insns.
2755 (define_expand "zero_extendhisi2"
2756 [(set (match_operand:SI 0 "register_operand" "")
2757 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2760 rtx temp = gen_reg_rtx (SImode);
2761 rtx shift_16 = GEN_INT (16);
2762 int op1_subbyte = 0;
2764 if (GET_CODE (operand1) == SUBREG)
2766 op1_subbyte = SUBREG_BYTE (operand1);
2767 op1_subbyte /= GET_MODE_SIZE (SImode);
2768 op1_subbyte *= GET_MODE_SIZE (SImode);
2769 operand1 = XEXP (operand1, 0);
2772 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2774 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2778 (define_insn "*zero_extendhisi2_insn"
2779 [(set (match_operand:SI 0 "register_operand" "=r")
2780 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2783 [(set_attr "type" "load")
2784 (set_attr "us3load_type" "3cycle")])
2786 (define_expand "zero_extendqihi2"
2787 [(set (match_operand:HI 0 "register_operand" "")
2788 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2792 (define_insn "*zero_extendqihi2_insn"
2793 [(set (match_operand:HI 0 "register_operand" "=r,r")
2794 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
2795 "GET_CODE (operands[1]) != CONST_INT"
2799 [(set_attr "type" "*,load")
2800 (set_attr "us3load_type" "*,3cycle")])
2802 (define_expand "zero_extendqisi2"
2803 [(set (match_operand:SI 0 "register_operand" "")
2804 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2808 (define_insn "*zero_extendqisi2_insn"
2809 [(set (match_operand:SI 0 "register_operand" "=r,r")
2810 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
2811 "GET_CODE (operands[1]) != CONST_INT"
2815 [(set_attr "type" "*,load")
2816 (set_attr "us3load_type" "*,3cycle")])
2818 (define_expand "zero_extendqidi2"
2819 [(set (match_operand:DI 0 "register_operand" "")
2820 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2824 (define_insn "*zero_extendqidi2_insn"
2825 [(set (match_operand:DI 0 "register_operand" "=r,r")
2826 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
2827 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2831 [(set_attr "type" "*,load")
2832 (set_attr "us3load_type" "*,3cycle")])
2834 (define_expand "zero_extendhidi2"
2835 [(set (match_operand:DI 0 "register_operand" "")
2836 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2839 rtx temp = gen_reg_rtx (DImode);
2840 rtx shift_48 = GEN_INT (48);
2841 int op1_subbyte = 0;
2843 if (GET_CODE (operand1) == SUBREG)
2845 op1_subbyte = SUBREG_BYTE (operand1);
2846 op1_subbyte /= GET_MODE_SIZE (DImode);
2847 op1_subbyte *= GET_MODE_SIZE (DImode);
2848 operand1 = XEXP (operand1, 0);
2851 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
2853 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
2857 (define_insn "*zero_extendhidi2_insn"
2858 [(set (match_operand:DI 0 "register_operand" "=r")
2859 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2862 [(set_attr "type" "load")
2863 (set_attr "us3load_type" "3cycle")])
2865 ;; ??? Write truncdisi pattern using sra?
2867 (define_expand "zero_extendsidi2"
2868 [(set (match_operand:DI 0 "register_operand" "")
2869 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
2873 (define_insn "*zero_extendsidi2_insn_sp64"
2874 [(set (match_operand:DI 0 "register_operand" "=r,r")
2875 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
2876 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2880 [(set_attr "type" "shift,load")])
2882 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
2883 [(set (match_operand:DI 0 "register_operand" "=r")
2884 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
2887 "&& reload_completed"
2888 [(set (match_dup 2) (match_dup 3))
2889 (set (match_dup 4) (match_dup 5))]
2893 dest1 = gen_highpart (SImode, operands[0]);
2894 dest2 = gen_lowpart (SImode, operands[0]);
2896 /* Swap the order in case of overlap. */
2897 if (REGNO (dest1) == REGNO (operands[1]))
2899 operands[2] = dest2;
2900 operands[3] = operands[1];
2901 operands[4] = dest1;
2902 operands[5] = const0_rtx;
2906 operands[2] = dest1;
2907 operands[3] = const0_rtx;
2908 operands[4] = dest2;
2909 operands[5] = operands[1];
2912 [(set_attr "length" "2")])
2914 ;; Simplify comparisons of extended values.
2916 (define_insn "*cmp_zero_extendqisi2"
2918 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
2921 "andcc\t%0, 0xff, %%g0"
2922 [(set_attr "type" "compare")])
2924 (define_insn "*cmp_zero_qi"
2926 (compare:CC (match_operand:QI 0 "register_operand" "r")
2929 "andcc\t%0, 0xff, %%g0"
2930 [(set_attr "type" "compare")])
2932 (define_insn "*cmp_zero_extendqisi2_set"
2934 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
2936 (set (match_operand:SI 0 "register_operand" "=r")
2937 (zero_extend:SI (match_dup 1)))]
2939 "andcc\t%1, 0xff, %0"
2940 [(set_attr "type" "compare")])
2942 (define_insn "*cmp_zero_extendqisi2_andcc_set"
2944 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
2947 (set (match_operand:SI 0 "register_operand" "=r")
2948 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
2950 "andcc\t%1, 0xff, %0"
2951 [(set_attr "type" "compare")])
2953 (define_insn "*cmp_zero_extendqidi2"
2955 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
2958 "andcc\t%0, 0xff, %%g0"
2959 [(set_attr "type" "compare")])
2961 (define_insn "*cmp_zero_qi_sp64"
2963 (compare:CCX (match_operand:QI 0 "register_operand" "r")
2966 "andcc\t%0, 0xff, %%g0"
2967 [(set_attr "type" "compare")])
2969 (define_insn "*cmp_zero_extendqidi2_set"
2971 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
2973 (set (match_operand:DI 0 "register_operand" "=r")
2974 (zero_extend:DI (match_dup 1)))]
2976 "andcc\t%1, 0xff, %0"
2977 [(set_attr "type" "compare")])
2979 (define_insn "*cmp_zero_extendqidi2_andcc_set"
2981 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
2984 (set (match_operand:DI 0 "register_operand" "=r")
2985 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
2987 "andcc\t%1, 0xff, %0"
2988 [(set_attr "type" "compare")])
2990 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
2992 (define_insn "*cmp_siqi_trunc"
2994 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
2997 "andcc\t%0, 0xff, %%g0"
2998 [(set_attr "type" "compare")])
3000 (define_insn "*cmp_siqi_trunc_set"
3002 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3004 (set (match_operand:QI 0 "register_operand" "=r")
3005 (subreg:QI (match_dup 1) 3))]
3007 "andcc\t%1, 0xff, %0"
3008 [(set_attr "type" "compare")])
3010 (define_insn "*cmp_diqi_trunc"
3012 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3015 "andcc\t%0, 0xff, %%g0"
3016 [(set_attr "type" "compare")])
3018 (define_insn "*cmp_diqi_trunc_set"
3020 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3022 (set (match_operand:QI 0 "register_operand" "=r")
3023 (subreg:QI (match_dup 1) 7))]
3025 "andcc\t%1, 0xff, %0"
3026 [(set_attr "type" "compare")])
3029 ;; Sign-extension instructions
3031 ;; These patterns originally accepted general_operands, however, slightly
3032 ;; better code is generated by only accepting register_operands, and then
3033 ;; letting combine generate the lds[hb] insns.
3035 (define_expand "extendhisi2"
3036 [(set (match_operand:SI 0 "register_operand" "")
3037 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3040 rtx temp = gen_reg_rtx (SImode);
3041 rtx shift_16 = GEN_INT (16);
3042 int op1_subbyte = 0;
3044 if (GET_CODE (operand1) == SUBREG)
3046 op1_subbyte = SUBREG_BYTE (operand1);
3047 op1_subbyte /= GET_MODE_SIZE (SImode);
3048 op1_subbyte *= GET_MODE_SIZE (SImode);
3049 operand1 = XEXP (operand1, 0);
3052 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3054 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3058 (define_insn "*sign_extendhisi2_insn"
3059 [(set (match_operand:SI 0 "register_operand" "=r")
3060 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3063 [(set_attr "type" "sload")
3064 (set_attr "us3load_type" "3cycle")])
3066 (define_expand "extendqihi2"
3067 [(set (match_operand:HI 0 "register_operand" "")
3068 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3071 rtx temp = gen_reg_rtx (SImode);
3072 rtx shift_24 = GEN_INT (24);
3073 int op1_subbyte = 0;
3074 int op0_subbyte = 0;
3076 if (GET_CODE (operand1) == SUBREG)
3078 op1_subbyte = SUBREG_BYTE (operand1);
3079 op1_subbyte /= GET_MODE_SIZE (SImode);
3080 op1_subbyte *= GET_MODE_SIZE (SImode);
3081 operand1 = XEXP (operand1, 0);
3083 if (GET_CODE (operand0) == SUBREG)
3085 op0_subbyte = SUBREG_BYTE (operand0);
3086 op0_subbyte /= GET_MODE_SIZE (SImode);
3087 op0_subbyte *= GET_MODE_SIZE (SImode);
3088 operand0 = XEXP (operand0, 0);
3090 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3092 if (GET_MODE (operand0) != SImode)
3093 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3094 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3098 (define_insn "*sign_extendqihi2_insn"
3099 [(set (match_operand:HI 0 "register_operand" "=r")
3100 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3103 [(set_attr "type" "sload")
3104 (set_attr "us3load_type" "3cycle")])
3106 (define_expand "extendqisi2"
3107 [(set (match_operand:SI 0 "register_operand" "")
3108 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3111 rtx temp = gen_reg_rtx (SImode);
3112 rtx shift_24 = GEN_INT (24);
3113 int op1_subbyte = 0;
3115 if (GET_CODE (operand1) == SUBREG)
3117 op1_subbyte = SUBREG_BYTE (operand1);
3118 op1_subbyte /= GET_MODE_SIZE (SImode);
3119 op1_subbyte *= GET_MODE_SIZE (SImode);
3120 operand1 = XEXP (operand1, 0);
3123 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3125 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3129 (define_insn "*sign_extendqisi2_insn"
3130 [(set (match_operand:SI 0 "register_operand" "=r")
3131 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3134 [(set_attr "type" "sload")
3135 (set_attr "us3load_type" "3cycle")])
3137 (define_expand "extendqidi2"
3138 [(set (match_operand:DI 0 "register_operand" "")
3139 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3142 rtx temp = gen_reg_rtx (DImode);
3143 rtx shift_56 = GEN_INT (56);
3144 int op1_subbyte = 0;
3146 if (GET_CODE (operand1) == SUBREG)
3148 op1_subbyte = SUBREG_BYTE (operand1);
3149 op1_subbyte /= GET_MODE_SIZE (DImode);
3150 op1_subbyte *= GET_MODE_SIZE (DImode);
3151 operand1 = XEXP (operand1, 0);
3154 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3156 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3160 (define_insn "*sign_extendqidi2_insn"
3161 [(set (match_operand:DI 0 "register_operand" "=r")
3162 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3165 [(set_attr "type" "sload")
3166 (set_attr "us3load_type" "3cycle")])
3168 (define_expand "extendhidi2"
3169 [(set (match_operand:DI 0 "register_operand" "")
3170 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3173 rtx temp = gen_reg_rtx (DImode);
3174 rtx shift_48 = GEN_INT (48);
3175 int op1_subbyte = 0;
3177 if (GET_CODE (operand1) == SUBREG)
3179 op1_subbyte = SUBREG_BYTE (operand1);
3180 op1_subbyte /= GET_MODE_SIZE (DImode);
3181 op1_subbyte *= GET_MODE_SIZE (DImode);
3182 operand1 = XEXP (operand1, 0);
3185 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3187 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3191 (define_insn "*sign_extendhidi2_insn"
3192 [(set (match_operand:DI 0 "register_operand" "=r")
3193 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3196 [(set_attr "type" "sload")
3197 (set_attr "us3load_type" "3cycle")])
3199 (define_expand "extendsidi2"
3200 [(set (match_operand:DI 0 "register_operand" "")
3201 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3205 (define_insn "*sign_extendsidi2_insn"
3206 [(set (match_operand:DI 0 "register_operand" "=r,r")
3207 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3212 [(set_attr "type" "shift,sload")
3213 (set_attr "us3load_type" "*,3cycle")])
3216 ;; Special pattern for optimizing bit-field compares. This is needed
3217 ;; because combine uses this as a canonical form.
3219 (define_insn "*cmp_zero_extract"
3222 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3223 (match_operand:SI 1 "small_int_operand" "I")
3224 (match_operand:SI 2 "small_int_operand" "I"))
3226 "INTVAL (operands[2]) > 19"
3228 int len = INTVAL (operands[1]);
3229 int pos = 32 - INTVAL (operands[2]) - len;
3230 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3231 operands[1] = GEN_INT (mask);
3232 return "andcc\t%0, %1, %%g0";
3234 [(set_attr "type" "compare")])
3236 (define_insn "*cmp_zero_extract_sp64"
3239 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3240 (match_operand:SI 1 "small_int_operand" "I")
3241 (match_operand:SI 2 "small_int_operand" "I"))
3243 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3245 int len = INTVAL (operands[1]);
3246 int pos = 64 - INTVAL (operands[2]) - len;
3247 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3248 operands[1] = GEN_INT (mask);
3249 return "andcc\t%0, %1, %%g0";
3251 [(set_attr "type" "compare")])
3254 ;; Conversions between float, double and long double.
3256 (define_insn "extendsfdf2"
3257 [(set (match_operand:DF 0 "register_operand" "=e")
3259 (match_operand:SF 1 "register_operand" "f")))]
3262 [(set_attr "type" "fp")
3263 (set_attr "fptype" "double")])
3265 (define_expand "extendsftf2"
3266 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3268 (match_operand:SF 1 "register_operand" "")))]
3269 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3270 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3272 (define_insn "*extendsftf2_hq"
3273 [(set (match_operand:TF 0 "register_operand" "=e")
3275 (match_operand:SF 1 "register_operand" "f")))]
3276 "TARGET_FPU && TARGET_HARD_QUAD"
3278 [(set_attr "type" "fp")])
3280 (define_expand "extenddftf2"
3281 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3283 (match_operand:DF 1 "register_operand" "")))]
3284 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3285 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3287 (define_insn "*extenddftf2_hq"
3288 [(set (match_operand:TF 0 "register_operand" "=e")
3290 (match_operand:DF 1 "register_operand" "e")))]
3291 "TARGET_FPU && TARGET_HARD_QUAD"
3293 [(set_attr "type" "fp")])
3295 (define_insn "truncdfsf2"
3296 [(set (match_operand:SF 0 "register_operand" "=f")
3298 (match_operand:DF 1 "register_operand" "e")))]
3301 [(set_attr "type" "fp")
3302 (set_attr "fptype" "double")])
3304 (define_expand "trunctfsf2"
3305 [(set (match_operand:SF 0 "register_operand" "")
3307 (match_operand:TF 1 "general_operand" "")))]
3308 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3309 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3311 (define_insn "*trunctfsf2_hq"
3312 [(set (match_operand:SF 0 "register_operand" "=f")
3314 (match_operand:TF 1 "register_operand" "e")))]
3315 "TARGET_FPU && TARGET_HARD_QUAD"
3317 [(set_attr "type" "fp")])
3319 (define_expand "trunctfdf2"
3320 [(set (match_operand:DF 0 "register_operand" "")
3322 (match_operand:TF 1 "general_operand" "")))]
3323 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3324 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3326 (define_insn "*trunctfdf2_hq"
3327 [(set (match_operand:DF 0 "register_operand" "=e")
3329 (match_operand:TF 1 "register_operand" "e")))]
3330 "TARGET_FPU && TARGET_HARD_QUAD"
3332 [(set_attr "type" "fp")])
3335 ;; Conversion between fixed point and floating point.
3337 (define_insn "floatsisf2"
3338 [(set (match_operand:SF 0 "register_operand" "=f")
3339 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3342 [(set_attr "type" "fp")
3343 (set_attr "fptype" "double")])
3345 (define_insn "floatsidf2"
3346 [(set (match_operand:DF 0 "register_operand" "=e")
3347 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3350 [(set_attr "type" "fp")
3351 (set_attr "fptype" "double")])
3353 (define_expand "floatsitf2"
3354 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3355 (float:TF (match_operand:SI 1 "register_operand" "")))]
3356 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3357 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3359 (define_insn "*floatsitf2_hq"
3360 [(set (match_operand:TF 0 "register_operand" "=e")
3361 (float:TF (match_operand:SI 1 "register_operand" "f")))]
3362 "TARGET_FPU && TARGET_HARD_QUAD"
3364 [(set_attr "type" "fp")])
3366 (define_expand "floatunssitf2"
3367 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3368 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3369 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3370 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3372 ;; Now the same for 64 bit sources.
3374 (define_insn "floatdisf2"
3375 [(set (match_operand:SF 0 "register_operand" "=f")
3376 (float:SF (match_operand:DI 1 "register_operand" "e")))]
3377 "TARGET_V9 && TARGET_FPU"
3379 [(set_attr "type" "fp")
3380 (set_attr "fptype" "double")])
3382 (define_expand "floatunsdisf2"
3383 [(use (match_operand:SF 0 "register_operand" ""))
3384 (use (match_operand:DI 1 "general_operand" ""))]
3385 "TARGET_ARCH64 && TARGET_FPU"
3386 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3388 (define_insn "floatdidf2"
3389 [(set (match_operand:DF 0 "register_operand" "=e")
3390 (float:DF (match_operand:DI 1 "register_operand" "e")))]
3391 "TARGET_V9 && TARGET_FPU"
3393 [(set_attr "type" "fp")
3394 (set_attr "fptype" "double")])
3396 (define_expand "floatunsdidf2"
3397 [(use (match_operand:DF 0 "register_operand" ""))
3398 (use (match_operand:DI 1 "general_operand" ""))]
3399 "TARGET_ARCH64 && TARGET_FPU"
3400 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3402 (define_expand "floatditf2"
3403 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3404 (float:TF (match_operand:DI 1 "register_operand" "")))]
3405 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3406 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3408 (define_insn "*floatditf2_hq"
3409 [(set (match_operand:TF 0 "register_operand" "=e")
3410 (float:TF (match_operand:DI 1 "register_operand" "e")))]
3411 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3413 [(set_attr "type" "fp")])
3415 (define_expand "floatunsditf2"
3416 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3417 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3418 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3419 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3421 ;; Convert a float to an actual integer.
3422 ;; Truncation is performed as part of the conversion.
3424 (define_insn "fix_truncsfsi2"
3425 [(set (match_operand:SI 0 "register_operand" "=f")
3426 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3429 [(set_attr "type" "fp")
3430 (set_attr "fptype" "double")])
3432 (define_insn "fix_truncdfsi2"
3433 [(set (match_operand:SI 0 "register_operand" "=f")
3434 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3437 [(set_attr "type" "fp")
3438 (set_attr "fptype" "double")])
3440 (define_expand "fix_trunctfsi2"
3441 [(set (match_operand:SI 0 "register_operand" "")
3442 (fix:SI (match_operand:TF 1 "general_operand" "")))]
3443 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3444 "emit_tfmode_cvt (FIX, operands); DONE;")
3446 (define_insn "*fix_trunctfsi2_hq"
3447 [(set (match_operand:SI 0 "register_operand" "=f")
3448 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
3449 "TARGET_FPU && TARGET_HARD_QUAD"
3451 [(set_attr "type" "fp")])
3453 (define_expand "fixuns_trunctfsi2"
3454 [(set (match_operand:SI 0 "register_operand" "")
3455 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
3456 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3457 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3459 ;; Now the same, for V9 targets
3461 (define_insn "fix_truncsfdi2"
3462 [(set (match_operand:DI 0 "register_operand" "=e")
3463 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3464 "TARGET_V9 && TARGET_FPU"
3466 [(set_attr "type" "fp")
3467 (set_attr "fptype" "double")])
3469 (define_expand "fixuns_truncsfdi2"
3470 [(use (match_operand:DI 0 "register_operand" ""))
3471 (use (match_operand:SF 1 "general_operand" ""))]
3472 "TARGET_ARCH64 && TARGET_FPU"
3473 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
3475 (define_insn "fix_truncdfdi2"
3476 [(set (match_operand:DI 0 "register_operand" "=e")
3477 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3478 "TARGET_V9 && TARGET_FPU"
3480 [(set_attr "type" "fp")
3481 (set_attr "fptype" "double")])
3483 (define_expand "fixuns_truncdfdi2"
3484 [(use (match_operand:DI 0 "register_operand" ""))
3485 (use (match_operand:DF 1 "general_operand" ""))]
3486 "TARGET_ARCH64 && TARGET_FPU"
3487 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
3489 (define_expand "fix_trunctfdi2"
3490 [(set (match_operand:DI 0 "register_operand" "")
3491 (fix:DI (match_operand:TF 1 "general_operand" "")))]
3492 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3493 "emit_tfmode_cvt (FIX, operands); DONE;")
3495 (define_insn "*fix_trunctfdi2_hq"
3496 [(set (match_operand:DI 0 "register_operand" "=e")
3497 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
3498 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3500 [(set_attr "type" "fp")])
3502 (define_expand "fixuns_trunctfdi2"
3503 [(set (match_operand:DI 0 "register_operand" "")
3504 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
3505 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3506 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3509 ;; Integer addition/subtraction instructions.
3511 (define_expand "adddi3"
3512 [(set (match_operand:DI 0 "register_operand" "")
3513 (plus:DI (match_operand:DI 1 "register_operand" "")
3514 (match_operand:DI 2 "arith_double_add_operand" "")))]
3517 if (! TARGET_ARCH64)
3519 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3520 gen_rtx_SET (VOIDmode, operands[0],
3521 gen_rtx_PLUS (DImode, operands[1],
3523 gen_rtx_CLOBBER (VOIDmode,
3524 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3529 (define_insn_and_split "*adddi3_insn_sp32"
3530 [(set (match_operand:DI 0 "register_operand" "=r")
3531 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3532 (match_operand:DI 2 "arith_double_operand" "rHI")))
3533 (clobber (reg:CC 100))]
3536 "&& reload_completed"
3537 [(parallel [(set (reg:CC_NOOV 100)
3538 (compare:CC_NOOV (plus:SI (match_dup 4)
3542 (plus:SI (match_dup 4) (match_dup 5)))])
3544 (plus:SI (plus:SI (match_dup 7)
3546 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3548 operands[3] = gen_lowpart (SImode, operands[0]);
3549 operands[4] = gen_lowpart (SImode, operands[1]);
3550 operands[5] = gen_lowpart (SImode, operands[2]);
3551 operands[6] = gen_highpart (SImode, operands[0]);
3552 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3553 #if HOST_BITS_PER_WIDE_INT == 32
3554 if (GET_CODE (operands[2]) == CONST_INT)
3556 if (INTVAL (operands[2]) < 0)
3557 operands[8] = constm1_rtx;
3559 operands[8] = const0_rtx;
3563 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3565 [(set_attr "length" "2")])
3567 ;; LTU here means "carry set"
3569 [(set (match_operand:SI 0 "register_operand" "=r")
3570 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3571 (match_operand:SI 2 "arith_operand" "rI"))
3572 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3575 [(set_attr "type" "ialuX")])
3577 (define_insn_and_split "*addx_extend_sp32"
3578 [(set (match_operand:DI 0 "register_operand" "=r")
3579 (zero_extend:DI (plus:SI (plus:SI
3580 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3581 (match_operand:SI 2 "arith_operand" "rI"))
3582 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3585 "&& reload_completed"
3586 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
3587 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
3588 (set (match_dup 4) (const_int 0))]
3589 "operands[3] = gen_lowpart (SImode, operands[0]);
3590 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
3591 [(set_attr "length" "2")])
3593 (define_insn "*addx_extend_sp64"
3594 [(set (match_operand:DI 0 "register_operand" "=r")
3595 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3596 (match_operand:SI 2 "arith_operand" "rI"))
3597 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3600 [(set_attr "type" "ialuX")])
3602 (define_insn_and_split "*adddi3_extend_sp32"
3603 [(set (match_operand:DI 0 "register_operand" "=r")
3604 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3605 (match_operand:DI 2 "register_operand" "r")))
3606 (clobber (reg:CC 100))]
3609 "&& reload_completed"
3610 [(parallel [(set (reg:CC_NOOV 100)
3611 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
3613 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
3615 (plus:SI (plus:SI (match_dup 4) (const_int 0))
3616 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3617 "operands[3] = gen_lowpart (SImode, operands[2]);
3618 operands[4] = gen_highpart (SImode, operands[2]);
3619 operands[5] = gen_lowpart (SImode, operands[0]);
3620 operands[6] = gen_highpart (SImode, operands[0]);"
3621 [(set_attr "length" "2")])
3623 (define_insn "*adddi3_sp64"
3624 [(set (match_operand:DI 0 "register_operand" "=r,r")
3625 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3626 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3632 (define_insn "addsi3"
3633 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3634 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
3635 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3640 fpadd32s\t%1, %2, %0"
3641 [(set_attr "type" "*,*,fga")
3642 (set_attr "fptype" "*,*,single")])
3644 (define_insn "*cmp_cc_plus"
3645 [(set (reg:CC_NOOV 100)
3646 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3647 (match_operand:SI 1 "arith_operand" "rI"))
3650 "addcc\t%0, %1, %%g0"
3651 [(set_attr "type" "compare")])
3653 (define_insn "*cmp_ccx_plus"
3654 [(set (reg:CCX_NOOV 100)
3655 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
3656 (match_operand:DI 1 "arith_operand" "rI"))
3659 "addcc\t%0, %1, %%g0"
3660 [(set_attr "type" "compare")])
3662 (define_insn "*cmp_cc_plus_set"
3663 [(set (reg:CC_NOOV 100)
3664 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3665 (match_operand:SI 2 "arith_operand" "rI"))
3667 (set (match_operand:SI 0 "register_operand" "=r")
3668 (plus:SI (match_dup 1) (match_dup 2)))]
3671 [(set_attr "type" "compare")])
3673 (define_insn "*cmp_ccx_plus_set"
3674 [(set (reg:CCX_NOOV 100)
3675 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
3676 (match_operand:DI 2 "arith_operand" "rI"))
3678 (set (match_operand:DI 0 "register_operand" "=r")
3679 (plus:DI (match_dup 1) (match_dup 2)))]
3682 [(set_attr "type" "compare")])
3684 (define_expand "subdi3"
3685 [(set (match_operand:DI 0 "register_operand" "")
3686 (minus:DI (match_operand:DI 1 "register_operand" "")
3687 (match_operand:DI 2 "arith_double_add_operand" "")))]
3690 if (! TARGET_ARCH64)
3692 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3693 gen_rtx_SET (VOIDmode, operands[0],
3694 gen_rtx_MINUS (DImode, operands[1],
3696 gen_rtx_CLOBBER (VOIDmode,
3697 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3702 (define_insn_and_split "*subdi3_insn_sp32"
3703 [(set (match_operand:DI 0 "register_operand" "=r")
3704 (minus:DI (match_operand:DI 1 "register_operand" "r")
3705 (match_operand:DI 2 "arith_double_operand" "rHI")))
3706 (clobber (reg:CC 100))]
3709 "&& reload_completed"
3710 [(parallel [(set (reg:CC_NOOV 100)
3711 (compare:CC_NOOV (minus:SI (match_dup 4)
3715 (minus:SI (match_dup 4) (match_dup 5)))])
3717 (minus:SI (minus:SI (match_dup 7)
3719 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3721 operands[3] = gen_lowpart (SImode, operands[0]);
3722 operands[4] = gen_lowpart (SImode, operands[1]);
3723 operands[5] = gen_lowpart (SImode, operands[2]);
3724 operands[6] = gen_highpart (SImode, operands[0]);
3725 operands[7] = gen_highpart (SImode, operands[1]);
3726 #if HOST_BITS_PER_WIDE_INT == 32
3727 if (GET_CODE (operands[2]) == CONST_INT)
3729 if (INTVAL (operands[2]) < 0)
3730 operands[8] = constm1_rtx;
3732 operands[8] = const0_rtx;
3736 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3738 [(set_attr "length" "2")])
3740 ;; LTU here means "carry set"
3742 [(set (match_operand:SI 0 "register_operand" "=r")
3743 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3744 (match_operand:SI 2 "arith_operand" "rI"))
3745 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3748 [(set_attr "type" "ialuX")])
3750 (define_insn "*subx_extend_sp64"
3751 [(set (match_operand:DI 0 "register_operand" "=r")
3752 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3753 (match_operand:SI 2 "arith_operand" "rI"))
3754 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3757 [(set_attr "type" "ialuX")])
3759 (define_insn_and_split "*subx_extend"
3760 [(set (match_operand:DI 0 "register_operand" "=r")
3761 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3762 (match_operand:SI 2 "arith_operand" "rI"))
3763 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3766 "&& reload_completed"
3767 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
3768 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
3769 (set (match_dup 4) (const_int 0))]
3770 "operands[3] = gen_lowpart (SImode, operands[0]);
3771 operands[4] = gen_highpart (SImode, operands[0]);"
3772 [(set_attr "length" "2")])
3774 (define_insn_and_split "*subdi3_extend_sp32"
3775 [(set (match_operand:DI 0 "register_operand" "=r")
3776 (minus:DI (match_operand:DI 1 "register_operand" "r")
3777 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
3778 (clobber (reg:CC 100))]
3781 "&& reload_completed"
3782 [(parallel [(set (reg:CC_NOOV 100)
3783 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
3785 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
3787 (minus:SI (minus:SI (match_dup 4) (const_int 0))
3788 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3789 "operands[3] = gen_lowpart (SImode, operands[1]);
3790 operands[4] = gen_highpart (SImode, operands[1]);
3791 operands[5] = gen_lowpart (SImode, operands[0]);
3792 operands[6] = gen_highpart (SImode, operands[0]);"
3793 [(set_attr "length" "2")])
3795 (define_insn "*subdi3_sp64"
3796 [(set (match_operand:DI 0 "register_operand" "=r,r")
3797 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
3798 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3804 (define_insn "subsi3"
3805 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3806 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
3807 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3812 fpsub32s\t%1, %2, %0"
3813 [(set_attr "type" "*,*,fga")
3814 (set_attr "fptype" "*,*,single")])
3816 (define_insn "*cmp_minus_cc"
3817 [(set (reg:CC_NOOV 100)
3818 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
3819 (match_operand:SI 1 "arith_operand" "rI"))
3822 "subcc\t%r0, %1, %%g0"
3823 [(set_attr "type" "compare")])
3825 (define_insn "*cmp_minus_ccx"
3826 [(set (reg:CCX_NOOV 100)
3827 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
3828 (match_operand:DI 1 "arith_operand" "rI"))
3831 "subcc\t%0, %1, %%g0"
3832 [(set_attr "type" "compare")])
3834 (define_insn "cmp_minus_cc_set"
3835 [(set (reg:CC_NOOV 100)
3836 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3837 (match_operand:SI 2 "arith_operand" "rI"))
3839 (set (match_operand:SI 0 "register_operand" "=r")
3840 (minus:SI (match_dup 1) (match_dup 2)))]
3842 "subcc\t%r1, %2, %0"
3843 [(set_attr "type" "compare")])
3845 (define_insn "*cmp_minus_ccx_set"
3846 [(set (reg:CCX_NOOV 100)
3847 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
3848 (match_operand:DI 2 "arith_operand" "rI"))
3850 (set (match_operand:DI 0 "register_operand" "=r")
3851 (minus:DI (match_dup 1) (match_dup 2)))]
3854 [(set_attr "type" "compare")])
3857 ;; Integer multiply/divide instructions.
3859 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
3860 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
3862 (define_insn "mulsi3"
3863 [(set (match_operand:SI 0 "register_operand" "=r")
3864 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3865 (match_operand:SI 2 "arith_operand" "rI")))]
3868 [(set_attr "type" "imul")])
3870 (define_expand "muldi3"
3871 [(set (match_operand:DI 0 "register_operand" "")
3872 (mult:DI (match_operand:DI 1 "arith_operand" "")
3873 (match_operand:DI 2 "arith_operand" "")))]
3874 "TARGET_ARCH64 || TARGET_V8PLUS"
3878 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
3883 (define_insn "*muldi3_sp64"
3884 [(set (match_operand:DI 0 "register_operand" "=r")
3885 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
3886 (match_operand:DI 2 "arith_operand" "rI")))]
3889 [(set_attr "type" "imul")])
3891 ;; V8plus wide multiply.
3893 (define_insn "muldi3_v8plus"
3894 [(set (match_operand:DI 0 "register_operand" "=r,h")
3895 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
3896 (match_operand:DI 2 "arith_operand" "rI,rI")))
3897 (clobber (match_scratch:SI 3 "=&h,X"))
3898 (clobber (match_scratch:SI 4 "=&h,X"))]
3901 if (sparc_check_64 (operands[1], insn) <= 0)
3902 output_asm_insn ("srl\t%L1, 0, %L1", operands);
3903 if (which_alternative == 1)
3904 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
3905 if (GET_CODE (operands[2]) == CONST_INT)
3907 if (which_alternative == 1)
3908 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
3910 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";
3912 else if (rtx_equal_p (operands[1], operands[2]))
3914 if (which_alternative == 1)
3915 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
3917 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";
3919 if (sparc_check_64 (operands[2], insn) <= 0)
3920 output_asm_insn ("srl\t%L2, 0, %L2", operands);
3921 if (which_alternative == 1)
3922 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";
3924 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";
3926 [(set_attr "type" "multi")
3927 (set_attr "length" "9,8")])
3929 (define_insn "*cmp_mul_set"
3931 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3932 (match_operand:SI 2 "arith_operand" "rI"))
3934 (set (match_operand:SI 0 "register_operand" "=r")
3935 (mult:SI (match_dup 1) (match_dup 2)))]
3936 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
3937 "smulcc\t%1, %2, %0"
3938 [(set_attr "type" "imul")])
3940 (define_expand "mulsidi3"
3941 [(set (match_operand:DI 0 "register_operand" "")
3942 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
3943 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
3946 if (CONSTANT_P (operands[2]))
3949 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
3951 else if (TARGET_ARCH32)
3952 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
3955 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
3961 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
3966 ;; V9 puts the 64-bit product in a 64-bit register. Only out or global
3967 ;; registers can hold 64-bit values in the V8plus environment.
3969 (define_insn "mulsidi3_v8plus"
3970 [(set (match_operand:DI 0 "register_operand" "=h,r")
3971 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
3972 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
3973 (clobber (match_scratch:SI 3 "=X,&h"))]
3976 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
3977 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
3978 [(set_attr "type" "multi")
3979 (set_attr "length" "2,3")])
3982 (define_insn "const_mulsidi3_v8plus"
3983 [(set (match_operand:DI 0 "register_operand" "=h,r")
3984 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
3985 (match_operand:DI 2 "small_int_operand" "I,I")))
3986 (clobber (match_scratch:SI 3 "=X,&h"))]
3989 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
3990 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
3991 [(set_attr "type" "multi")
3992 (set_attr "length" "2,3")])
3995 (define_insn "*mulsidi3_sp32"
3996 [(set (match_operand:DI 0 "register_operand" "=r")
3997 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3998 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4001 return TARGET_SPARCLET
4002 ? "smuld\t%1, %2, %L0"
4003 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4006 (if_then_else (eq_attr "isa" "sparclet")
4007 (const_string "imul") (const_string "multi")))
4008 (set (attr "length")
4009 (if_then_else (eq_attr "isa" "sparclet")
4010 (const_int 1) (const_int 2)))])
4012 (define_insn "*mulsidi3_sp64"
4013 [(set (match_operand:DI 0 "register_operand" "=r")
4014 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4015 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4016 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4018 [(set_attr "type" "imul")])
4020 ;; Extra pattern, because sign_extend of a constant isn't valid.
4023 (define_insn "const_mulsidi3_sp32"
4024 [(set (match_operand:DI 0 "register_operand" "=r")
4025 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4026 (match_operand:DI 2 "small_int_operand" "I")))]
4029 return TARGET_SPARCLET
4030 ? "smuld\t%1, %2, %L0"
4031 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4034 (if_then_else (eq_attr "isa" "sparclet")
4035 (const_string "imul") (const_string "multi")))
4036 (set (attr "length")
4037 (if_then_else (eq_attr "isa" "sparclet")
4038 (const_int 1) (const_int 2)))])
4040 (define_insn "const_mulsidi3_sp64"
4041 [(set (match_operand:DI 0 "register_operand" "=r")
4042 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4043 (match_operand:DI 2 "small_int_operand" "I")))]
4044 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4046 [(set_attr "type" "imul")])
4048 (define_expand "smulsi3_highpart"
4049 [(set (match_operand:SI 0 "register_operand" "")
4051 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4052 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4054 "TARGET_HARD_MUL && TARGET_ARCH32"
4056 if (CONSTANT_P (operands[2]))
4060 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4066 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4071 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4072 operands[2], GEN_INT (32)));
4078 (define_insn "smulsi3_highpart_v8plus"
4079 [(set (match_operand:SI 0 "register_operand" "=h,r")
4081 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4082 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4083 (match_operand:SI 3 "small_int_operand" "I,I"))))
4084 (clobber (match_scratch:SI 4 "=X,&h"))]
4087 smul\t%1, %2, %0\;srlx\t%0, %3, %0
4088 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4089 [(set_attr "type" "multi")
4090 (set_attr "length" "2")])
4092 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4095 [(set (match_operand:SI 0 "register_operand" "=h,r")
4098 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4099 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4100 (match_operand:SI 3 "small_int_operand" "I,I"))
4102 (clobber (match_scratch:SI 4 "=X,&h"))]
4105 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4106 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4107 [(set_attr "type" "multi")
4108 (set_attr "length" "2")])
4111 (define_insn "const_smulsi3_highpart_v8plus"
4112 [(set (match_operand:SI 0 "register_operand" "=h,r")
4114 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4115 (match_operand:DI 2 "small_int_operand" "I,I"))
4116 (match_operand:SI 3 "small_int_operand" "I,I"))))
4117 (clobber (match_scratch:SI 4 "=X,&h"))]
4120 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4121 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4122 [(set_attr "type" "multi")
4123 (set_attr "length" "2")])
4126 (define_insn "*smulsi3_highpart_sp32"
4127 [(set (match_operand:SI 0 "register_operand" "=r")
4129 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4130 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4133 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4134 [(set_attr "type" "multi")
4135 (set_attr "length" "2")])
4138 (define_insn "const_smulsi3_highpart"
4139 [(set (match_operand:SI 0 "register_operand" "=r")
4141 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4142 (match_operand:DI 2 "small_int_operand" "i"))
4145 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4146 [(set_attr "type" "multi")
4147 (set_attr "length" "2")])
4149 (define_expand "umulsidi3"
4150 [(set (match_operand:DI 0 "register_operand" "")
4151 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4152 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4155 if (CONSTANT_P (operands[2]))
4158 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4160 else if (TARGET_ARCH32)
4161 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4164 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4170 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4176 (define_insn "umulsidi3_v8plus"
4177 [(set (match_operand:DI 0 "register_operand" "=h,r")
4178 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4179 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4180 (clobber (match_scratch:SI 3 "=X,&h"))]
4183 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4184 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4185 [(set_attr "type" "multi")
4186 (set_attr "length" "2,3")])
4189 (define_insn "*umulsidi3_sp32"
4190 [(set (match_operand:DI 0 "register_operand" "=r")
4191 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4192 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4195 return TARGET_SPARCLET
4196 ? "umuld\t%1, %2, %L0"
4197 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4200 (if_then_else (eq_attr "isa" "sparclet")
4201 (const_string "imul") (const_string "multi")))
4202 (set (attr "length")
4203 (if_then_else (eq_attr "isa" "sparclet")
4204 (const_int 1) (const_int 2)))])
4206 (define_insn "*umulsidi3_sp64"
4207 [(set (match_operand:DI 0 "register_operand" "=r")
4208 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4209 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4210 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4212 [(set_attr "type" "imul")])
4214 ;; Extra pattern, because sign_extend of a constant isn't valid.
4217 (define_insn "const_umulsidi3_sp32"
4218 [(set (match_operand:DI 0 "register_operand" "=r")
4219 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4220 (match_operand:DI 2 "uns_small_int_operand" "")))]
4223 return TARGET_SPARCLET
4224 ? "umuld\t%1, %s2, %L0"
4225 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4228 (if_then_else (eq_attr "isa" "sparclet")
4229 (const_string "imul") (const_string "multi")))
4230 (set (attr "length")
4231 (if_then_else (eq_attr "isa" "sparclet")
4232 (const_int 1) (const_int 2)))])
4234 (define_insn "const_umulsidi3_sp64"
4235 [(set (match_operand:DI 0 "register_operand" "=r")
4236 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4237 (match_operand:DI 2 "uns_small_int_operand" "")))]
4238 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4240 [(set_attr "type" "imul")])
4243 (define_insn "const_umulsidi3_v8plus"
4244 [(set (match_operand:DI 0 "register_operand" "=h,r")
4245 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4246 (match_operand:DI 2 "uns_small_int_operand" "")))
4247 (clobber (match_scratch:SI 3 "=X,h"))]
4250 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4251 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4252 [(set_attr "type" "multi")
4253 (set_attr "length" "2,3")])
4255 (define_expand "umulsi3_highpart"
4256 [(set (match_operand:SI 0 "register_operand" "")
4258 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4259 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4261 "TARGET_HARD_MUL && TARGET_ARCH32"
4263 if (CONSTANT_P (operands[2]))
4267 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4273 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4278 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4279 operands[2], GEN_INT (32)));
4285 (define_insn "umulsi3_highpart_v8plus"
4286 [(set (match_operand:SI 0 "register_operand" "=h,r")
4288 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4289 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4290 (match_operand:SI 3 "small_int_operand" "I,I"))))
4291 (clobber (match_scratch:SI 4 "=X,h"))]
4294 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4295 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4296 [(set_attr "type" "multi")
4297 (set_attr "length" "2")])
4300 (define_insn "const_umulsi3_highpart_v8plus"
4301 [(set (match_operand:SI 0 "register_operand" "=h,r")
4303 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4304 (match_operand:DI 2 "uns_small_int_operand" ""))
4305 (match_operand:SI 3 "small_int_operand" "I,I"))))
4306 (clobber (match_scratch:SI 4 "=X,h"))]
4309 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4310 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4311 [(set_attr "type" "multi")
4312 (set_attr "length" "2")])
4315 (define_insn "*umulsi3_highpart_sp32"
4316 [(set (match_operand:SI 0 "register_operand" "=r")
4318 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4319 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4322 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4323 [(set_attr "type" "multi")
4324 (set_attr "length" "2")])
4327 (define_insn "const_umulsi3_highpart"
4328 [(set (match_operand:SI 0 "register_operand" "=r")
4330 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4331 (match_operand:DI 2 "uns_small_int_operand" ""))
4334 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4335 [(set_attr "type" "multi")
4336 (set_attr "length" "2")])
4338 (define_expand "divsi3"
4339 [(parallel [(set (match_operand:SI 0 "register_operand" "")
4340 (div:SI (match_operand:SI 1 "register_operand" "")
4341 (match_operand:SI 2 "input_operand" "")))
4342 (clobber (match_scratch:SI 3 ""))])]
4343 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4347 operands[3] = gen_reg_rtx(SImode);
4348 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4349 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4355 ;; The V8 architecture specifies that there must be at least 3 instructions
4356 ;; between a write to the Y register and a use of it for correct results.
4357 ;; We try to fill one of them with a simple constant or a memory load.
4359 (define_insn "divsi3_sp32"
4360 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4361 (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4362 (match_operand:SI 2 "input_operand" "rI,K,m")))
4363 (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4364 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4366 output_asm_insn ("sra\t%1, 31, %3", operands);
4367 output_asm_insn ("wr\t%3, 0, %%y", operands);
4369 switch (which_alternative)
4373 return "sdiv\t%1, %2, %0";
4375 return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4378 return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4380 return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4383 return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4385 return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4390 [(set_attr "type" "multi")
4391 (set (attr "length")
4392 (if_then_else (eq_attr "isa" "v9")
4393 (const_int 4) (const_int 6)))])
4395 (define_insn "divsi3_sp64"
4396 [(set (match_operand:SI 0 "register_operand" "=r")
4397 (div:SI (match_operand:SI 1 "register_operand" "r")
4398 (match_operand:SI 2 "input_operand" "rI")))
4399 (use (match_operand:SI 3 "register_operand" "r"))]
4400 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4401 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4402 [(set_attr "type" "multi")
4403 (set_attr "length" "2")])
4405 (define_insn "divdi3"
4406 [(set (match_operand:DI 0 "register_operand" "=r")
4407 (div:DI (match_operand:DI 1 "register_operand" "r")
4408 (match_operand:DI 2 "arith_operand" "rI")))]
4411 [(set_attr "type" "idiv")])
4413 (define_insn "*cmp_sdiv_cc_set"
4415 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4416 (match_operand:SI 2 "arith_operand" "rI"))
4418 (set (match_operand:SI 0 "register_operand" "=r")
4419 (div:SI (match_dup 1) (match_dup 2)))
4420 (clobber (match_scratch:SI 3 "=&r"))]
4421 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4423 output_asm_insn ("sra\t%1, 31, %3", operands);
4424 output_asm_insn ("wr\t%3, 0, %%y", operands);
4427 return "sdivcc\t%1, %2, %0";
4429 return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4431 [(set_attr "type" "multi")
4432 (set (attr "length")
4433 (if_then_else (eq_attr "isa" "v9")
4434 (const_int 3) (const_int 6)))])
4437 (define_expand "udivsi3"
4438 [(set (match_operand:SI 0 "register_operand" "")
4439 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4440 (match_operand:SI 2 "input_operand" "")))]
4441 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4444 ;; The V8 architecture specifies that there must be at least 3 instructions
4445 ;; between a write to the Y register and a use of it for correct results.
4446 ;; We try to fill one of them with a simple constant or a memory load.
4448 (define_insn "udivsi3_sp32"
4449 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
4450 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
4451 (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
4452 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4454 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4456 switch (which_alternative)
4460 return "udiv\t%1, %2, %0";
4462 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
4465 return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
4467 return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4470 return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
4472 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4475 return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
4477 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
4482 [(set_attr "type" "multi")
4483 (set (attr "length")
4484 (if_then_else (eq_attr "isa" "v9")
4485 (const_int 3) (const_int 5)))])
4487 (define_insn "udivsi3_sp64"
4488 [(set (match_operand:SI 0 "register_operand" "=r")
4489 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
4490 (match_operand:SI 2 "input_operand" "rI")))]
4491 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4492 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
4493 [(set_attr "type" "multi")
4494 (set_attr "length" "2")])
4496 (define_insn "udivdi3"
4497 [(set (match_operand:DI 0 "register_operand" "=r")
4498 (udiv:DI (match_operand:DI 1 "register_operand" "r")
4499 (match_operand:DI 2 "arith_operand" "rI")))]
4502 [(set_attr "type" "idiv")])
4504 (define_insn "*cmp_udiv_cc_set"
4506 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
4507 (match_operand:SI 2 "arith_operand" "rI"))
4509 (set (match_operand:SI 0 "register_operand" "=r")
4510 (udiv:SI (match_dup 1) (match_dup 2)))]
4511 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4513 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4516 return "udivcc\t%1, %2, %0";
4518 return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
4520 [(set_attr "type" "multi")
4521 (set (attr "length")
4522 (if_then_else (eq_attr "isa" "v9")
4523 (const_int 2) (const_int 5)))])
4525 ; sparclet multiply/accumulate insns
4527 (define_insn "*smacsi"
4528 [(set (match_operand:SI 0 "register_operand" "=r")
4529 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
4530 (match_operand:SI 2 "arith_operand" "rI"))
4531 (match_operand:SI 3 "register_operand" "0")))]
4534 [(set_attr "type" "imul")])
4536 (define_insn "*smacdi"
4537 [(set (match_operand:DI 0 "register_operand" "=r")
4538 (plus:DI (mult:DI (sign_extend:DI
4539 (match_operand:SI 1 "register_operand" "%r"))
4541 (match_operand:SI 2 "register_operand" "r")))
4542 (match_operand:DI 3 "register_operand" "0")))]
4544 "smacd\t%1, %2, %L0"
4545 [(set_attr "type" "imul")])
4547 (define_insn "*umacdi"
4548 [(set (match_operand:DI 0 "register_operand" "=r")
4549 (plus:DI (mult:DI (zero_extend:DI
4550 (match_operand:SI 1 "register_operand" "%r"))
4552 (match_operand:SI 2 "register_operand" "r")))
4553 (match_operand:DI 3 "register_operand" "0")))]
4555 "umacd\t%1, %2, %L0"
4556 [(set_attr "type" "imul")])
4559 ;; Boolean instructions.
4561 ;; We define DImode `and' so with DImode `not' we can get
4562 ;; DImode `andn'. Other combinations are possible.
4564 (define_expand "and<V64I:mode>3"
4565 [(set (match_operand:V64I 0 "register_operand" "")
4566 (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
4567 (match_operand:V64I 2 "arith_double_operand" "")))]
4571 (define_insn "*and<V64I:mode>3_sp32"
4572 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4573 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4574 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4579 [(set_attr "type" "*,fga")
4580 (set_attr "length" "2,*")
4581 (set_attr "fptype" "*,double")])
4583 (define_insn "*and<V64I:mode>3_sp64"
4584 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4585 (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4586 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4591 [(set_attr "type" "*,fga")
4592 (set_attr "fptype" "*,double")])
4594 (define_insn "and<V32I:mode>3"
4595 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4596 (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4597 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4602 [(set_attr "type" "*,fga")
4603 (set_attr "fptype" "*,single")])
4606 [(set (match_operand:SI 0 "register_operand" "")
4607 (and:SI (match_operand:SI 1 "register_operand" "")
4608 (match_operand:SI 2 "const_compl_high_operand" "")))
4609 (clobber (match_operand:SI 3 "register_operand" ""))]
4611 [(set (match_dup 3) (match_dup 4))
4612 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
4614 operands[4] = GEN_INT (~INTVAL (operands[2]));
4617 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
4618 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4619 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4620 (match_operand:V64I 2 "register_operand" "r,b")))]
4624 fandnot1\t%1, %2, %0"
4625 "&& reload_completed
4626 && ((GET_CODE (operands[0]) == REG
4627 && REGNO (operands[0]) < 32)
4628 || (GET_CODE (operands[0]) == SUBREG
4629 && GET_CODE (SUBREG_REG (operands[0])) == REG
4630 && REGNO (SUBREG_REG (operands[0])) < 32))"
4631 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
4632 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
4633 "operands[3] = gen_highpart (SImode, operands[0]);
4634 operands[4] = gen_highpart (SImode, operands[1]);
4635 operands[5] = gen_highpart (SImode, operands[2]);
4636 operands[6] = gen_lowpart (SImode, operands[0]);
4637 operands[7] = gen_lowpart (SImode, operands[1]);
4638 operands[8] = gen_lowpart (SImode, operands[2]);"
4639 [(set_attr "type" "*,fga")
4640 (set_attr "length" "2,*")
4641 (set_attr "fptype" "*,double")])
4643 (define_insn "*and_not_<V64I:mode>_sp64"
4644 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4645 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4646 (match_operand:V64I 2 "register_operand" "r,b")))]
4650 fandnot1\t%1, %2, %0"
4651 [(set_attr "type" "*,fga")
4652 (set_attr "fptype" "*,double")])
4654 (define_insn "*and_not_<V32I:mode>"
4655 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4656 (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
4657 (match_operand:V32I 2 "register_operand" "r,d")))]
4661 fandnot1s\t%1, %2, %0"
4662 [(set_attr "type" "*,fga")
4663 (set_attr "fptype" "*,single")])
4665 (define_expand "ior<V64I:mode>3"
4666 [(set (match_operand:V64I 0 "register_operand" "")
4667 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
4668 (match_operand:V64I 2 "arith_double_operand" "")))]
4672 (define_insn "*ior<V64I:mode>3_sp32"
4673 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4674 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4675 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4680 [(set_attr "type" "*,fga")
4681 (set_attr "length" "2,*")
4682 (set_attr "fptype" "*,double")])
4684 (define_insn "*ior<V64I:mode>3_sp64"
4685 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4686 (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4687 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4692 [(set_attr "type" "*,fga")
4693 (set_attr "fptype" "*,double")])
4695 (define_insn "ior<V32I:mode>3"
4696 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4697 (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4698 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4703 [(set_attr "type" "*,fga")
4704 (set_attr "fptype" "*,single")])
4707 [(set (match_operand:SI 0 "register_operand" "")
4708 (ior:SI (match_operand:SI 1 "register_operand" "")
4709 (match_operand:SI 2 "const_compl_high_operand" "")))
4710 (clobber (match_operand:SI 3 "register_operand" ""))]
4712 [(set (match_dup 3) (match_dup 4))
4713 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4715 operands[4] = GEN_INT (~INTVAL (operands[2]));
4718 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
4719 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4720 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4721 (match_operand:V64I 2 "register_operand" "r,b")))]
4725 fornot1\t%1, %2, %0"
4726 "&& reload_completed
4727 && ((GET_CODE (operands[0]) == REG
4728 && REGNO (operands[0]) < 32)
4729 || (GET_CODE (operands[0]) == SUBREG
4730 && GET_CODE (SUBREG_REG (operands[0])) == REG
4731 && REGNO (SUBREG_REG (operands[0])) < 32))"
4732 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
4733 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
4734 "operands[3] = gen_highpart (SImode, operands[0]);
4735 operands[4] = gen_highpart (SImode, operands[1]);
4736 operands[5] = gen_highpart (SImode, operands[2]);
4737 operands[6] = gen_lowpart (SImode, operands[0]);
4738 operands[7] = gen_lowpart (SImode, operands[1]);
4739 operands[8] = gen_lowpart (SImode, operands[2]);"
4740 [(set_attr "type" "*,fga")
4741 (set_attr "length" "2,*")
4742 (set_attr "fptype" "*,double")])
4744 (define_insn "*or_not_<V64I:mode>_sp64"
4745 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4746 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4747 (match_operand:V64I 2 "register_operand" "r,b")))]
4751 fornot1\t%1, %2, %0"
4752 [(set_attr "type" "*,fga")
4753 (set_attr "fptype" "*,double")])
4755 (define_insn "*or_not_<V32I:mode>"
4756 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4757 (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
4758 (match_operand:V32I 2 "register_operand" "r,d")))]
4762 fornot1s\t%1, %2, %0"
4763 [(set_attr "type" "*,fga")
4764 (set_attr "fptype" "*,single")])
4766 (define_expand "xor<V64I:mode>3"
4767 [(set (match_operand:V64I 0 "register_operand" "")
4768 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
4769 (match_operand:V64I 2 "arith_double_operand" "")))]
4773 (define_insn "*xor<V64I:mode>3_sp32"
4774 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4775 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4776 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4781 [(set_attr "type" "*,fga")
4782 (set_attr "length" "2,*")
4783 (set_attr "fptype" "*,double")])
4785 (define_insn "*xor<V64I:mode>3_sp64"
4786 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4787 (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
4788 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4793 [(set_attr "type" "*,fga")
4794 (set_attr "fptype" "*,double")])
4796 (define_insn "xor<V32I:mode>3"
4797 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4798 (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
4799 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4804 [(set_attr "type" "*,fga")
4805 (set_attr "fptype" "*,single")])
4808 [(set (match_operand:SI 0 "register_operand" "")
4809 (xor:SI (match_operand:SI 1 "register_operand" "")
4810 (match_operand:SI 2 "const_compl_high_operand" "")))
4811 (clobber (match_operand:SI 3 "register_operand" ""))]
4813 [(set (match_dup 3) (match_dup 4))
4814 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4816 operands[4] = GEN_INT (~INTVAL (operands[2]));
4820 [(set (match_operand:SI 0 "register_operand" "")
4821 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
4822 (match_operand:SI 2 "const_compl_high_operand" ""))))
4823 (clobber (match_operand:SI 3 "register_operand" ""))]
4825 [(set (match_dup 3) (match_dup 4))
4826 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
4828 operands[4] = GEN_INT (~INTVAL (operands[2]));
4831 ;; Split DImode logical operations requiring two instructions.
4833 [(set (match_operand:V64I 0 "register_operand" "")
4834 (match_operator:V64I 1 "cc_arith_operator" ; AND, IOR, XOR
4835 [(match_operand:V64I 2 "register_operand" "")
4836 (match_operand:V64I 3 "arith_double_operand" "")]))]
4839 && ((GET_CODE (operands[0]) == REG
4840 && REGNO (operands[0]) < 32)
4841 || (GET_CODE (operands[0]) == SUBREG
4842 && GET_CODE (SUBREG_REG (operands[0])) == REG
4843 && REGNO (SUBREG_REG (operands[0])) < 32))"
4844 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
4845 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
4847 operands[4] = gen_highpart (SImode, operands[0]);
4848 operands[5] = gen_lowpart (SImode, operands[0]);
4849 operands[6] = gen_highpart (SImode, operands[2]);
4850 operands[7] = gen_lowpart (SImode, operands[2]);
4851 #if HOST_BITS_PER_WIDE_INT == 32
4852 if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
4854 if (INTVAL (operands[3]) < 0)
4855 operands[8] = constm1_rtx;
4857 operands[8] = const0_rtx;
4861 operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
4862 operands[9] = gen_lowpart (SImode, operands[3]);
4865 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
4866 ;; Combine now canonicalizes to the rightmost expression.
4867 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
4868 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4869 (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
4870 (match_operand:V64I 2 "register_operand" "r,b"))))]
4875 "&& reload_completed
4876 && ((GET_CODE (operands[0]) == REG
4877 && REGNO (operands[0]) < 32)
4878 || (GET_CODE (operands[0]) == SUBREG
4879 && GET_CODE (SUBREG_REG (operands[0])) == REG
4880 && REGNO (SUBREG_REG (operands[0])) < 32))"
4881 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
4882 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
4883 "operands[3] = gen_highpart (SImode, operands[0]);
4884 operands[4] = gen_highpart (SImode, operands[1]);
4885 operands[5] = gen_highpart (SImode, operands[2]);
4886 operands[6] = gen_lowpart (SImode, operands[0]);
4887 operands[7] = gen_lowpart (SImode, operands[1]);
4888 operands[8] = gen_lowpart (SImode, operands[2]);"
4889 [(set_attr "type" "*,fga")
4890 (set_attr "length" "2,*")
4891 (set_attr "fptype" "*,double")])
4893 (define_insn "*xor_not_<V64I:mode>_sp64"
4894 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4895 (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
4896 (match_operand:V64I 2 "arith_operand" "rI,b"))))]
4901 [(set_attr "type" "*,fga")
4902 (set_attr "fptype" "*,double")])
4904 (define_insn "*xor_not_<V32I:mode>"
4905 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4906 (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
4907 (match_operand:V32I 2 "arith_operand" "rI,d"))))]
4912 [(set_attr "type" "*,fga")
4913 (set_attr "fptype" "*,single")])
4915 ;; These correspond to the above in the case where we also (or only)
4916 ;; want to set the condition code.
4918 (define_insn "*cmp_cc_arith_op"
4921 (match_operator:SI 2 "cc_arith_operator"
4922 [(match_operand:SI 0 "arith_operand" "%r")
4923 (match_operand:SI 1 "arith_operand" "rI")])
4926 "%A2cc\t%0, %1, %%g0"
4927 [(set_attr "type" "compare")])
4929 (define_insn "*cmp_ccx_arith_op"
4932 (match_operator:DI 2 "cc_arith_operator"
4933 [(match_operand:DI 0 "arith_operand" "%r")
4934 (match_operand:DI 1 "arith_operand" "rI")])
4937 "%A2cc\t%0, %1, %%g0"
4938 [(set_attr "type" "compare")])
4940 (define_insn "*cmp_cc_arith_op_set"
4943 (match_operator:SI 3 "cc_arith_operator"
4944 [(match_operand:SI 1 "arith_operand" "%r")
4945 (match_operand:SI 2 "arith_operand" "rI")])
4947 (set (match_operand:SI 0 "register_operand" "=r")
4948 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
4949 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
4951 [(set_attr "type" "compare")])
4953 (define_insn "*cmp_ccx_arith_op_set"
4956 (match_operator:DI 3 "cc_arith_operator"
4957 [(match_operand:DI 1 "arith_operand" "%r")
4958 (match_operand:DI 2 "arith_operand" "rI")])
4960 (set (match_operand:DI 0 "register_operand" "=r")
4961 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
4962 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
4964 [(set_attr "type" "compare")])
4966 (define_insn "*cmp_cc_xor_not"
4969 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
4970 (match_operand:SI 1 "arith_operand" "rI")))
4973 "xnorcc\t%r0, %1, %%g0"
4974 [(set_attr "type" "compare")])
4976 (define_insn "*cmp_ccx_xor_not"
4979 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
4980 (match_operand:DI 1 "arith_operand" "rI")))
4983 "xnorcc\t%r0, %1, %%g0"
4984 [(set_attr "type" "compare")])
4986 (define_insn "*cmp_cc_xor_not_set"
4989 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4990 (match_operand:SI 2 "arith_operand" "rI")))
4992 (set (match_operand:SI 0 "register_operand" "=r")
4993 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
4995 "xnorcc\t%r1, %2, %0"
4996 [(set_attr "type" "compare")])
4998 (define_insn "*cmp_ccx_xor_not_set"
5001 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5002 (match_operand:DI 2 "arith_operand" "rI")))
5004 (set (match_operand:DI 0 "register_operand" "=r")
5005 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5007 "xnorcc\t%r1, %2, %0"
5008 [(set_attr "type" "compare")])
5010 (define_insn "*cmp_cc_arith_op_not"
5013 (match_operator:SI 2 "cc_arith_not_operator"
5014 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5015 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5018 "%B2cc\t%r1, %0, %%g0"
5019 [(set_attr "type" "compare")])
5021 (define_insn "*cmp_ccx_arith_op_not"
5024 (match_operator:DI 2 "cc_arith_not_operator"
5025 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5026 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5029 "%B2cc\t%r1, %0, %%g0"
5030 [(set_attr "type" "compare")])
5032 (define_insn "*cmp_cc_arith_op_not_set"
5035 (match_operator:SI 3 "cc_arith_not_operator"
5036 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5037 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5039 (set (match_operand:SI 0 "register_operand" "=r")
5040 (match_operator:SI 4 "cc_arith_not_operator"
5041 [(not:SI (match_dup 1)) (match_dup 2)]))]
5042 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5043 "%B3cc\t%r2, %1, %0"
5044 [(set_attr "type" "compare")])
5046 (define_insn "*cmp_ccx_arith_op_not_set"
5049 (match_operator:DI 3 "cc_arith_not_operator"
5050 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5051 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5053 (set (match_operand:DI 0 "register_operand" "=r")
5054 (match_operator:DI 4 "cc_arith_not_operator"
5055 [(not:DI (match_dup 1)) (match_dup 2)]))]
5056 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5057 "%B3cc\t%r2, %1, %0"
5058 [(set_attr "type" "compare")])
5060 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5061 ;; does not know how to make it work for constants.
5063 (define_expand "negdi2"
5064 [(set (match_operand:DI 0 "register_operand" "=r")
5065 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5068 if (! TARGET_ARCH64)
5070 emit_insn (gen_rtx_PARALLEL
5073 gen_rtx_SET (VOIDmode, operand0,
5074 gen_rtx_NEG (DImode, operand1)),
5075 gen_rtx_CLOBBER (VOIDmode,
5076 gen_rtx_REG (CCmode,
5082 (define_insn_and_split "*negdi2_sp32"
5083 [(set (match_operand:DI 0 "register_operand" "=r")
5084 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5085 (clobber (reg:CC 100))]
5088 "&& reload_completed"
5089 [(parallel [(set (reg:CC_NOOV 100)
5090 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5092 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5093 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5094 (ltu:SI (reg:CC 100) (const_int 0))))]
5095 "operands[2] = gen_highpart (SImode, operands[0]);
5096 operands[3] = gen_highpart (SImode, operands[1]);
5097 operands[4] = gen_lowpart (SImode, operands[0]);
5098 operands[5] = gen_lowpart (SImode, operands[1]);"
5099 [(set_attr "length" "2")])
5101 (define_insn "*negdi2_sp64"
5102 [(set (match_operand:DI 0 "register_operand" "=r")
5103 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5105 "sub\t%%g0, %1, %0")
5107 (define_insn "negsi2"
5108 [(set (match_operand:SI 0 "register_operand" "=r")
5109 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5111 "sub\t%%g0, %1, %0")
5113 (define_insn "*cmp_cc_neg"
5114 [(set (reg:CC_NOOV 100)
5115 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5118 "subcc\t%%g0, %0, %%g0"
5119 [(set_attr "type" "compare")])
5121 (define_insn "*cmp_ccx_neg"
5122 [(set (reg:CCX_NOOV 100)
5123 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5126 "subcc\t%%g0, %0, %%g0"
5127 [(set_attr "type" "compare")])
5129 (define_insn "*cmp_cc_set_neg"
5130 [(set (reg:CC_NOOV 100)
5131 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5133 (set (match_operand:SI 0 "register_operand" "=r")
5134 (neg:SI (match_dup 1)))]
5136 "subcc\t%%g0, %1, %0"
5137 [(set_attr "type" "compare")])
5139 (define_insn "*cmp_ccx_set_neg"
5140 [(set (reg:CCX_NOOV 100)
5141 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5143 (set (match_operand:DI 0 "register_operand" "=r")
5144 (neg:DI (match_dup 1)))]
5146 "subcc\t%%g0, %1, %0"
5147 [(set_attr "type" "compare")])
5149 ;; We cannot use the "not" pseudo insn because the Sun assembler
5150 ;; does not know how to make it work for constants.
5151 (define_expand "one_cmpl<V64I:mode>2"
5152 [(set (match_operand:V64I 0 "register_operand" "")
5153 (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5157 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5158 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5159 (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5164 "&& reload_completed
5165 && ((GET_CODE (operands[0]) == REG
5166 && REGNO (operands[0]) < 32)
5167 || (GET_CODE (operands[0]) == SUBREG
5168 && GET_CODE (SUBREG_REG (operands[0])) == REG
5169 && REGNO (SUBREG_REG (operands[0])) < 32))"
5170 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5171 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5172 "operands[2] = gen_highpart (SImode, operands[0]);
5173 operands[3] = gen_highpart (SImode, operands[1]);
5174 operands[4] = gen_lowpart (SImode, operands[0]);
5175 operands[5] = gen_lowpart (SImode, operands[1]);"
5176 [(set_attr "type" "*,fga")
5177 (set_attr "length" "2,*")
5178 (set_attr "fptype" "*,double")])
5180 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5181 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5182 (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5187 [(set_attr "type" "*,fga")
5188 (set_attr "fptype" "*,double")])
5190 (define_insn "one_cmpl<V32I:mode>2"
5191 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5192 (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5197 [(set_attr "type" "*,fga")
5198 (set_attr "fptype" "*,single")])
5200 (define_insn "*cmp_cc_not"
5202 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5205 "xnorcc\t%%g0, %0, %%g0"
5206 [(set_attr "type" "compare")])
5208 (define_insn "*cmp_ccx_not"
5210 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5213 "xnorcc\t%%g0, %0, %%g0"
5214 [(set_attr "type" "compare")])
5216 (define_insn "*cmp_cc_set_not"
5218 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5220 (set (match_operand:SI 0 "register_operand" "=r")
5221 (not:SI (match_dup 1)))]
5223 "xnorcc\t%%g0, %1, %0"
5224 [(set_attr "type" "compare")])
5226 (define_insn "*cmp_ccx_set_not"
5228 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5230 (set (match_operand:DI 0 "register_operand" "=r")
5231 (not:DI (match_dup 1)))]
5233 "xnorcc\t%%g0, %1, %0"
5234 [(set_attr "type" "compare")])
5236 (define_insn "*cmp_cc_set"
5237 [(set (match_operand:SI 0 "register_operand" "=r")
5238 (match_operand:SI 1 "register_operand" "r"))
5240 (compare:CC (match_dup 1)
5244 [(set_attr "type" "compare")])
5246 (define_insn "*cmp_ccx_set64"
5247 [(set (match_operand:DI 0 "register_operand" "=r")
5248 (match_operand:DI 1 "register_operand" "r"))
5250 (compare:CCX (match_dup 1)
5254 [(set_attr "type" "compare")])
5257 ;; Floating point arithmetic instructions.
5259 (define_expand "addtf3"
5260 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5261 (plus:TF (match_operand:TF 1 "general_operand" "")
5262 (match_operand:TF 2 "general_operand" "")))]
5263 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5264 "emit_tfmode_binop (PLUS, operands); DONE;")
5266 (define_insn "*addtf3_hq"
5267 [(set (match_operand:TF 0 "register_operand" "=e")
5268 (plus:TF (match_operand:TF 1 "register_operand" "e")
5269 (match_operand:TF 2 "register_operand" "e")))]
5270 "TARGET_FPU && TARGET_HARD_QUAD"
5272 [(set_attr "type" "fp")])
5274 (define_insn "adddf3"
5275 [(set (match_operand:DF 0 "register_operand" "=e")
5276 (plus:DF (match_operand:DF 1 "register_operand" "e")
5277 (match_operand:DF 2 "register_operand" "e")))]
5280 [(set_attr "type" "fp")
5281 (set_attr "fptype" "double")])
5283 (define_insn "addsf3"
5284 [(set (match_operand:SF 0 "register_operand" "=f")
5285 (plus:SF (match_operand:SF 1 "register_operand" "f")
5286 (match_operand:SF 2 "register_operand" "f")))]
5289 [(set_attr "type" "fp")])
5291 (define_expand "subtf3"
5292 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5293 (minus:TF (match_operand:TF 1 "general_operand" "")
5294 (match_operand:TF 2 "general_operand" "")))]
5295 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5296 "emit_tfmode_binop (MINUS, operands); DONE;")
5298 (define_insn "*subtf3_hq"
5299 [(set (match_operand:TF 0 "register_operand" "=e")
5300 (minus:TF (match_operand:TF 1 "register_operand" "e")
5301 (match_operand:TF 2 "register_operand" "e")))]
5302 "TARGET_FPU && TARGET_HARD_QUAD"
5304 [(set_attr "type" "fp")])
5306 (define_insn "subdf3"
5307 [(set (match_operand:DF 0 "register_operand" "=e")
5308 (minus:DF (match_operand:DF 1 "register_operand" "e")
5309 (match_operand:DF 2 "register_operand" "e")))]
5312 [(set_attr "type" "fp")
5313 (set_attr "fptype" "double")])
5315 (define_insn "subsf3"
5316 [(set (match_operand:SF 0 "register_operand" "=f")
5317 (minus:SF (match_operand:SF 1 "register_operand" "f")
5318 (match_operand:SF 2 "register_operand" "f")))]
5321 [(set_attr "type" "fp")])
5323 (define_expand "multf3"
5324 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5325 (mult:TF (match_operand:TF 1 "general_operand" "")
5326 (match_operand:TF 2 "general_operand" "")))]
5327 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5328 "emit_tfmode_binop (MULT, operands); DONE;")
5330 (define_insn "*multf3_hq"
5331 [(set (match_operand:TF 0 "register_operand" "=e")
5332 (mult:TF (match_operand:TF 1 "register_operand" "e")
5333 (match_operand:TF 2 "register_operand" "e")))]
5334 "TARGET_FPU && TARGET_HARD_QUAD"
5336 [(set_attr "type" "fpmul")])
5338 (define_insn "muldf3"
5339 [(set (match_operand:DF 0 "register_operand" "=e")
5340 (mult:DF (match_operand:DF 1 "register_operand" "e")
5341 (match_operand:DF 2 "register_operand" "e")))]
5344 [(set_attr "type" "fpmul")
5345 (set_attr "fptype" "double")])
5347 (define_insn "mulsf3"
5348 [(set (match_operand:SF 0 "register_operand" "=f")
5349 (mult:SF (match_operand:SF 1 "register_operand" "f")
5350 (match_operand:SF 2 "register_operand" "f")))]
5353 [(set_attr "type" "fpmul")])
5355 (define_insn "*muldf3_extend"
5356 [(set (match_operand:DF 0 "register_operand" "=e")
5357 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5358 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5359 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
5360 "fsmuld\t%1, %2, %0"
5361 [(set_attr "type" "fpmul")
5362 (set_attr "fptype" "double")])
5364 (define_insn "*multf3_extend"
5365 [(set (match_operand:TF 0 "register_operand" "=e")
5366 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5367 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5368 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5369 "fdmulq\t%1, %2, %0"
5370 [(set_attr "type" "fpmul")])
5372 (define_expand "divtf3"
5373 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5374 (div:TF (match_operand:TF 1 "general_operand" "")
5375 (match_operand:TF 2 "general_operand" "")))]
5376 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5377 "emit_tfmode_binop (DIV, operands); DONE;")
5379 ;; don't have timing for quad-prec. divide.
5380 (define_insn "*divtf3_hq"
5381 [(set (match_operand:TF 0 "register_operand" "=e")
5382 (div:TF (match_operand:TF 1 "register_operand" "e")
5383 (match_operand:TF 2 "register_operand" "e")))]
5384 "TARGET_FPU && TARGET_HARD_QUAD"
5386 [(set_attr "type" "fpdivd")])
5388 (define_insn "divdf3"
5389 [(set (match_operand:DF 0 "register_operand" "=e")
5390 (div:DF (match_operand:DF 1 "register_operand" "e")
5391 (match_operand:DF 2 "register_operand" "e")))]
5394 [(set_attr "type" "fpdivd")
5395 (set_attr "fptype" "double")])
5397 (define_insn "divsf3"
5398 [(set (match_operand:SF 0 "register_operand" "=f")
5399 (div:SF (match_operand:SF 1 "register_operand" "f")
5400 (match_operand:SF 2 "register_operand" "f")))]
5403 [(set_attr "type" "fpdivs")])
5405 (define_expand "negtf2"
5406 [(set (match_operand:TF 0 "register_operand" "=e,e")
5407 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5411 (define_insn_and_split "*negtf2_notv9"
5412 [(set (match_operand:TF 0 "register_operand" "=e,e")
5413 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5414 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5420 "&& reload_completed
5421 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5422 [(set (match_dup 2) (neg:SF (match_dup 3)))
5423 (set (match_dup 4) (match_dup 5))
5424 (set (match_dup 6) (match_dup 7))]
5425 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5426 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5427 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5428 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5429 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5430 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5431 [(set_attr "type" "fpmove,*")
5432 (set_attr "length" "*,2")])
5434 (define_insn_and_split "*negtf2_v9"
5435 [(set (match_operand:TF 0 "register_operand" "=e,e")
5436 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5437 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5438 "TARGET_FPU && TARGET_V9"
5442 "&& reload_completed
5443 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5444 [(set (match_dup 2) (neg:DF (match_dup 3)))
5445 (set (match_dup 4) (match_dup 5))]
5446 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5447 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5448 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5449 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5450 [(set_attr "type" "fpmove,*")
5451 (set_attr "length" "*,2")
5452 (set_attr "fptype" "double")])
5454 (define_expand "negdf2"
5455 [(set (match_operand:DF 0 "register_operand" "")
5456 (neg:DF (match_operand:DF 1 "register_operand" "")))]
5460 (define_insn_and_split "*negdf2_notv9"
5461 [(set (match_operand:DF 0 "register_operand" "=e,e")
5462 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
5463 "TARGET_FPU && ! TARGET_V9"
5467 "&& reload_completed
5468 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5469 [(set (match_dup 2) (neg:SF (match_dup 3)))
5470 (set (match_dup 4) (match_dup 5))]
5471 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5472 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5473 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5474 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5475 [(set_attr "type" "fpmove,*")
5476 (set_attr "length" "*,2")])
5478 (define_insn "*negdf2_v9"
5479 [(set (match_operand:DF 0 "register_operand" "=e")
5480 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5481 "TARGET_FPU && TARGET_V9"
5483 [(set_attr "type" "fpmove")
5484 (set_attr "fptype" "double")])
5486 (define_insn "negsf2"
5487 [(set (match_operand:SF 0 "register_operand" "=f")
5488 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
5491 [(set_attr "type" "fpmove")])
5493 (define_expand "abstf2"
5494 [(set (match_operand:TF 0 "register_operand" "")
5495 (abs:TF (match_operand:TF 1 "register_operand" "")))]
5499 (define_insn_and_split "*abstf2_notv9"
5500 [(set (match_operand:TF 0 "register_operand" "=e,e")
5501 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5502 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5503 "TARGET_FPU && ! TARGET_V9"
5507 "&& reload_completed
5508 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5509 [(set (match_dup 2) (abs:SF (match_dup 3)))
5510 (set (match_dup 4) (match_dup 5))
5511 (set (match_dup 6) (match_dup 7))]
5512 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5513 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5514 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5515 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5516 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5517 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5518 [(set_attr "type" "fpmove,*")
5519 (set_attr "length" "*,2")])
5521 (define_insn "*abstf2_hq_v9"
5522 [(set (match_operand:TF 0 "register_operand" "=e,e")
5523 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5524 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
5528 [(set_attr "type" "fpmove")
5529 (set_attr "fptype" "double,*")])
5531 (define_insn_and_split "*abstf2_v9"
5532 [(set (match_operand:TF 0 "register_operand" "=e,e")
5533 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5534 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
5538 "&& reload_completed
5539 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5540 [(set (match_dup 2) (abs:DF (match_dup 3)))
5541 (set (match_dup 4) (match_dup 5))]
5542 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5543 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5544 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5545 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5546 [(set_attr "type" "fpmove,*")
5547 (set_attr "length" "*,2")
5548 (set_attr "fptype" "double,*")])
5550 (define_expand "absdf2"
5551 [(set (match_operand:DF 0 "register_operand" "")
5552 (abs:DF (match_operand:DF 1 "register_operand" "")))]
5556 (define_insn_and_split "*absdf2_notv9"
5557 [(set (match_operand:DF 0 "register_operand" "=e,e")
5558 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
5559 "TARGET_FPU && ! TARGET_V9"
5563 "&& reload_completed
5564 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5565 [(set (match_dup 2) (abs:SF (match_dup 3)))
5566 (set (match_dup 4) (match_dup 5))]
5567 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5568 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5569 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5570 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5571 [(set_attr "type" "fpmove,*")
5572 (set_attr "length" "*,2")])
5574 (define_insn "*absdf2_v9"
5575 [(set (match_operand:DF 0 "register_operand" "=e")
5576 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5577 "TARGET_FPU && TARGET_V9"
5579 [(set_attr "type" "fpmove")
5580 (set_attr "fptype" "double")])
5582 (define_insn "abssf2"
5583 [(set (match_operand:SF 0 "register_operand" "=f")
5584 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
5587 [(set_attr "type" "fpmove")])
5589 (define_expand "sqrttf2"
5590 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5591 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
5592 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5593 "emit_tfmode_unop (SQRT, operands); DONE;")
5595 (define_insn "*sqrttf2_hq"
5596 [(set (match_operand:TF 0 "register_operand" "=e")
5597 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
5598 "TARGET_FPU && TARGET_HARD_QUAD"
5600 [(set_attr "type" "fpsqrtd")])
5602 (define_insn "sqrtdf2"
5603 [(set (match_operand:DF 0 "register_operand" "=e")
5604 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5607 [(set_attr "type" "fpsqrtd")
5608 (set_attr "fptype" "double")])
5610 (define_insn "sqrtsf2"
5611 [(set (match_operand:SF 0 "register_operand" "=f")
5612 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
5615 [(set_attr "type" "fpsqrts")])
5618 ;; Arithmetic shift instructions.
5620 (define_insn "ashlsi3"
5621 [(set (match_operand:SI 0 "register_operand" "=r")
5622 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5623 (match_operand:SI 2 "arith_operand" "rI")))]
5626 if (GET_CODE (operands[2]) == CONST_INT)
5627 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5628 return "sll\t%1, %2, %0";
5631 (if_then_else (match_operand 2 "const_one_operand" "")
5632 (const_string "ialu") (const_string "shift")))])
5634 (define_expand "ashldi3"
5635 [(set (match_operand:DI 0 "register_operand" "=r")
5636 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5637 (match_operand:SI 2 "arith_operand" "rI")))]
5638 "TARGET_ARCH64 || TARGET_V8PLUS"
5640 if (! TARGET_ARCH64)
5642 if (GET_CODE (operands[2]) == CONST_INT)
5644 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
5649 (define_insn "*ashldi3_sp64"
5650 [(set (match_operand:DI 0 "register_operand" "=r")
5651 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5652 (match_operand:SI 2 "arith_operand" "rI")))]
5655 if (GET_CODE (operands[2]) == CONST_INT)
5656 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5657 return "sllx\t%1, %2, %0";
5660 (if_then_else (match_operand 2 "const_one_operand" "")
5661 (const_string "ialu") (const_string "shift")))])
5664 (define_insn "ashldi3_v8plus"
5665 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5666 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5667 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5668 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5670 "* return output_v8plus_shift (operands, insn, \"sllx\");"
5671 [(set_attr "type" "multi")
5672 (set_attr "length" "5,5,6")])
5674 ;; Optimize (1LL<<x)-1
5675 ;; XXX this also needs to be fixed to handle equal subregs
5676 ;; XXX first before we could re-enable it.
5678 ; [(set (match_operand:DI 0 "register_operand" "=h")
5679 ; (plus:DI (ashift:DI (const_int 1)
5680 ; (match_operand:SI 1 "arith_operand" "rI"))
5682 ; "0 && TARGET_V8PLUS"
5684 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
5685 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5686 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5688 ; [(set_attr "type" "multi")
5689 ; (set_attr "length" "4")])
5691 (define_insn "*cmp_cc_ashift_1"
5692 [(set (reg:CC_NOOV 100)
5693 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
5697 "addcc\t%0, %0, %%g0"
5698 [(set_attr "type" "compare")])
5700 (define_insn "*cmp_cc_set_ashift_1"
5701 [(set (reg:CC_NOOV 100)
5702 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
5705 (set (match_operand:SI 0 "register_operand" "=r")
5706 (ashift:SI (match_dup 1) (const_int 1)))]
5709 [(set_attr "type" "compare")])
5711 (define_insn "ashrsi3"
5712 [(set (match_operand:SI 0 "register_operand" "=r")
5713 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5714 (match_operand:SI 2 "arith_operand" "rI")))]
5717 if (GET_CODE (operands[2]) == CONST_INT)
5718 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5719 return "sra\t%1, %2, %0";
5721 [(set_attr "type" "shift")])
5723 (define_insn "*ashrsi3_extend"
5724 [(set (match_operand:DI 0 "register_operand" "=r")
5725 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5726 (match_operand:SI 2 "arith_operand" "r"))))]
5729 [(set_attr "type" "shift")])
5731 ;; This handles the case as above, but with constant shift instead of
5732 ;; register. Combiner "simplifies" it for us a little bit though.
5733 (define_insn "*ashrsi3_extend2"
5734 [(set (match_operand:DI 0 "register_operand" "=r")
5735 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5737 (match_operand:SI 2 "small_int_operand" "I")))]
5738 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
5740 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5741 return "sra\t%1, %2, %0";
5743 [(set_attr "type" "shift")])
5745 (define_expand "ashrdi3"
5746 [(set (match_operand:DI 0 "register_operand" "=r")
5747 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5748 (match_operand:SI 2 "arith_operand" "rI")))]
5749 "TARGET_ARCH64 || TARGET_V8PLUS"
5751 if (! TARGET_ARCH64)
5753 if (GET_CODE (operands[2]) == CONST_INT)
5754 FAIL; /* prefer generic code in this case */
5755 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
5760 (define_insn "*ashrdi3_sp64"
5761 [(set (match_operand:DI 0 "register_operand" "=r")
5762 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5763 (match_operand:SI 2 "arith_operand" "rI")))]
5767 if (GET_CODE (operands[2]) == CONST_INT)
5768 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5769 return "srax\t%1, %2, %0";
5771 [(set_attr "type" "shift")])
5774 (define_insn "ashrdi3_v8plus"
5775 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5776 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5777 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5778 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5780 "* return output_v8plus_shift (operands, insn, \"srax\");"
5781 [(set_attr "type" "multi")
5782 (set_attr "length" "5,5,6")])
5784 (define_insn "lshrsi3"
5785 [(set (match_operand:SI 0 "register_operand" "=r")
5786 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5787 (match_operand:SI 2 "arith_operand" "rI")))]
5790 if (GET_CODE (operands[2]) == CONST_INT)
5791 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5792 return "srl\t%1, %2, %0";
5794 [(set_attr "type" "shift")])
5796 ;; This handles the case where
5797 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
5798 ;; but combiner "simplifies" it for us.
5799 (define_insn "*lshrsi3_extend"
5800 [(set (match_operand:DI 0 "register_operand" "=r")
5801 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5802 (match_operand:SI 2 "arith_operand" "r")) 0)
5803 (match_operand 3 "const_int_operand" "")))]
5804 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
5806 [(set_attr "type" "shift")])
5808 ;; This handles the case where
5809 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
5810 ;; but combiner "simplifies" it for us.
5811 (define_insn "*lshrsi3_extend2"
5812 [(set (match_operand:DI 0 "register_operand" "=r")
5813 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5814 (match_operand 2 "small_int_operand" "I")
5816 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5818 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
5819 return "srl\t%1, %2, %0";
5821 [(set_attr "type" "shift")])
5823 (define_expand "lshrdi3"
5824 [(set (match_operand:DI 0 "register_operand" "=r")
5825 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5826 (match_operand:SI 2 "arith_operand" "rI")))]
5827 "TARGET_ARCH64 || TARGET_V8PLUS"
5829 if (! TARGET_ARCH64)
5831 if (GET_CODE (operands[2]) == CONST_INT)
5833 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
5838 (define_insn "*lshrdi3_sp64"
5839 [(set (match_operand:DI 0 "register_operand" "=r")
5840 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5841 (match_operand:SI 2 "arith_operand" "rI")))]
5844 if (GET_CODE (operands[2]) == CONST_INT)
5845 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5846 return "srlx\t%1, %2, %0";
5848 [(set_attr "type" "shift")])
5851 (define_insn "lshrdi3_v8plus"
5852 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5853 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5854 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5855 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5857 "* return output_v8plus_shift (operands, insn, \"srlx\");"
5858 [(set_attr "type" "multi")
5859 (set_attr "length" "5,5,6")])
5862 [(set (match_operand:SI 0 "register_operand" "=r")
5863 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5865 (match_operand:SI 2 "small_int_operand" "I")))]
5866 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5868 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
5869 return "srax\t%1, %2, %0";
5871 [(set_attr "type" "shift")])
5874 [(set (match_operand:SI 0 "register_operand" "=r")
5875 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5877 (match_operand:SI 2 "small_int_operand" "I")))]
5878 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5880 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
5881 return "srlx\t%1, %2, %0";
5883 [(set_attr "type" "shift")])
5886 [(set (match_operand:SI 0 "register_operand" "=r")
5887 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5888 (match_operand:SI 2 "small_int_operand" "I")) 4)
5889 (match_operand:SI 3 "small_int_operand" "I")))]
5891 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
5892 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
5893 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
5895 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
5897 return "srax\t%1, %2, %0";
5899 [(set_attr "type" "shift")])
5902 [(set (match_operand:SI 0 "register_operand" "=r")
5903 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5904 (match_operand:SI 2 "small_int_operand" "I")) 4)
5905 (match_operand:SI 3 "small_int_operand" "I")))]
5907 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
5908 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
5909 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
5911 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
5913 return "srlx\t%1, %2, %0";
5915 [(set_attr "type" "shift")])
5918 ;; Unconditional and other jump instructions.
5921 [(set (pc) (label_ref (match_operand 0 "" "")))]
5923 "* return output_ubranch (operands[0], 0, insn);"
5924 [(set_attr "type" "uncond_branch")])
5926 (define_expand "tablejump"
5927 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
5928 (use (label_ref (match_operand 1 "" "")))])]
5931 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
5933 /* In pic mode, our address differences are against the base of the
5934 table. Add that base value back in; CSE ought to be able to combine
5935 the two address loads. */
5939 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
5941 if (CASE_VECTOR_MODE != Pmode)
5942 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
5943 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
5944 operands[0] = memory_address (Pmode, tmp);
5948 (define_insn "*tablejump_sp32"
5949 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
5950 (use (label_ref (match_operand 1 "" "")))]
5953 [(set_attr "type" "uncond_branch")])
5955 (define_insn "*tablejump_sp64"
5956 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
5957 (use (label_ref (match_operand 1 "" "")))]
5960 [(set_attr "type" "uncond_branch")])
5963 ;; Jump to subroutine instructions.
5965 (define_expand "call"
5966 ;; Note that this expression is not used for generating RTL.
5967 ;; All the RTL is generated explicitly below.
5968 [(call (match_operand 0 "call_operand" "")
5969 (match_operand 3 "" "i"))]
5970 ;; operands[2] is next_arg_register
5971 ;; operands[3] is struct_value_size_rtx.
5976 gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
5978 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
5980 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
5982 /* This is really a PIC sequence. We want to represent
5983 it as a funny jump so its delay slots can be filled.
5985 ??? But if this really *is* a CALL, will not it clobber the
5986 call-clobbered registers? We lose this if it is a JUMP_INSN.
5987 Why cannot we have delay slots filled if it were a CALL? */
5989 /* We accept negative sizes for untyped calls. */
5990 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
5995 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
5997 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6003 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6004 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6008 fn_rtx = operands[0];
6010 /* We accept negative sizes for untyped calls. */
6011 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6012 sparc_emit_call_insn
6015 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6017 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6020 sparc_emit_call_insn
6023 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6024 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6032 ;; We can't use the same pattern for these two insns, because then registers
6033 ;; in the address may not be properly reloaded.
6035 (define_insn "*call_address_sp32"
6036 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6037 (match_operand 1 "" ""))
6038 (clobber (reg:SI 15))]
6039 ;;- Do not use operand 1 for most machines.
6042 [(set_attr "type" "call")])
6044 (define_insn "*call_symbolic_sp32"
6045 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6046 (match_operand 1 "" ""))
6047 (clobber (reg:SI 15))]
6048 ;;- Do not use operand 1 for most machines.
6051 [(set_attr "type" "call")])
6053 (define_insn "*call_address_sp64"
6054 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6055 (match_operand 1 "" ""))
6056 (clobber (reg:DI 15))]
6057 ;;- Do not use operand 1 for most machines.
6060 [(set_attr "type" "call")])
6062 (define_insn "*call_symbolic_sp64"
6063 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6064 (match_operand 1 "" ""))
6065 (clobber (reg:DI 15))]
6066 ;;- Do not use operand 1 for most machines.
6069 [(set_attr "type" "call")])
6071 ;; This is a call that wants a structure value.
6072 ;; There is no such critter for v9 (??? we may need one anyway).
6073 (define_insn "*call_address_struct_value_sp32"
6074 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6075 (match_operand 1 "" ""))
6076 (match_operand 2 "immediate_operand" "")
6077 (clobber (reg:SI 15))]
6078 ;;- Do not use operand 1 for most machines.
6079 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6081 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6082 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6084 [(set_attr "type" "call_no_delay_slot")
6085 (set_attr "length" "3")])
6087 ;; This is a call that wants a structure value.
6088 ;; There is no such critter for v9 (??? we may need one anyway).
6089 (define_insn "*call_symbolic_struct_value_sp32"
6090 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6091 (match_operand 1 "" ""))
6092 (match_operand 2 "immediate_operand" "")
6093 (clobber (reg:SI 15))]
6094 ;;- Do not use operand 1 for most machines.
6095 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6097 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6098 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6100 [(set_attr "type" "call_no_delay_slot")
6101 (set_attr "length" "3")])
6103 ;; This is a call that may want a structure value. This is used for
6105 (define_insn "*call_address_untyped_struct_value_sp32"
6106 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6107 (match_operand 1 "" ""))
6108 (match_operand 2 "immediate_operand" "")
6109 (clobber (reg:SI 15))]
6110 ;;- Do not use operand 1 for most machines.
6111 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6112 "call\t%a0, %1\n\t nop\n\tnop"
6113 [(set_attr "type" "call_no_delay_slot")
6114 (set_attr "length" "3")])
6116 ;; This is a call that may want a structure value. This is used for
6118 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6119 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6120 (match_operand 1 "" ""))
6121 (match_operand 2 "immediate_operand" "")
6122 (clobber (reg:SI 15))]
6123 ;;- Do not use operand 1 for most machines.
6124 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6125 "call\t%a0, %1\n\t nop\n\tnop"
6126 [(set_attr "type" "call_no_delay_slot")
6127 (set_attr "length" "3")])
6129 (define_expand "call_value"
6130 ;; Note that this expression is not used for generating RTL.
6131 ;; All the RTL is generated explicitly below.
6132 [(set (match_operand 0 "register_operand" "=rf")
6133 (call (match_operand 1 "" "")
6134 (match_operand 4 "" "")))]
6135 ;; operand 2 is stack_size_rtx
6136 ;; operand 3 is next_arg_register
6142 gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6144 fn_rtx = operands[1];
6147 gen_rtx_SET (VOIDmode, operands[0],
6148 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6149 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6151 sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6156 (define_insn "*call_value_address_sp32"
6157 [(set (match_operand 0 "" "=rf")
6158 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6159 (match_operand 2 "" "")))
6160 (clobber (reg:SI 15))]
6161 ;;- Do not use operand 2 for most machines.
6164 [(set_attr "type" "call")])
6166 (define_insn "*call_value_symbolic_sp32"
6167 [(set (match_operand 0 "" "=rf")
6168 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6169 (match_operand 2 "" "")))
6170 (clobber (reg:SI 15))]
6171 ;;- Do not use operand 2 for most machines.
6174 [(set_attr "type" "call")])
6176 (define_insn "*call_value_address_sp64"
6177 [(set (match_operand 0 "" "")
6178 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6179 (match_operand 2 "" "")))
6180 (clobber (reg:DI 15))]
6181 ;;- Do not use operand 2 for most machines.
6184 [(set_attr "type" "call")])
6186 (define_insn "*call_value_symbolic_sp64"
6187 [(set (match_operand 0 "" "")
6188 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6189 (match_operand 2 "" "")))
6190 (clobber (reg:DI 15))]
6191 ;;- Do not use operand 2 for most machines.
6194 [(set_attr "type" "call")])
6196 (define_expand "untyped_call"
6197 [(parallel [(call (match_operand 0 "" "")
6199 (match_operand:BLK 1 "memory_operand" "")
6200 (match_operand 2 "" "")])]
6203 rtx valreg1 = gen_rtx_REG (DImode, 8);
6204 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6205 rtx result = operands[1];
6207 /* Pass constm1 to indicate that it may expect a structure value, but
6208 we don't know what size it is. */
6209 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6211 /* Save the function value registers. */
6212 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6213 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6216 /* The optimizer does not know that the call sets the function value
6217 registers we stored in the result block. We avoid problems by
6218 claiming that all hard registers are used and clobbered at this
6220 emit_insn (gen_blockage ());
6225 ;; Tail call instructions.
6227 (define_expand "sibcall"
6228 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6233 (define_insn "*sibcall_symbolic_sp32"
6234 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6235 (match_operand 1 "" ""))
6238 "* return output_sibcall(insn, operands[0]);"
6239 [(set_attr "type" "sibcall")])
6241 (define_insn "*sibcall_symbolic_sp64"
6242 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6243 (match_operand 1 "" ""))
6246 "* return output_sibcall(insn, operands[0]);"
6247 [(set_attr "type" "sibcall")])
6249 (define_expand "sibcall_value"
6250 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6251 (call (match_operand 1 "" "") (const_int 0)))
6256 (define_insn "*sibcall_value_symbolic_sp32"
6257 [(set (match_operand 0 "" "=rf")
6258 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6259 (match_operand 2 "" "")))
6262 "* return output_sibcall(insn, operands[1]);"
6263 [(set_attr "type" "sibcall")])
6265 (define_insn "*sibcall_value_symbolic_sp64"
6266 [(set (match_operand 0 "" "")
6267 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6268 (match_operand 2 "" "")))
6271 "* return output_sibcall(insn, operands[1]);"
6272 [(set_attr "type" "sibcall")])
6275 ;; Special instructions.
6277 (define_expand "prologue"
6282 sparc_flat_expand_prologue ();
6284 sparc_expand_prologue ();
6288 ;; The "register window save" insn is modelled as follows. The dwarf2
6289 ;; information is manually added in emit_window_save.
6291 (define_insn "window_save"
6293 [(match_operand 0 "arith_operand" "rI")]
6296 "save\t%%sp, %0, %%sp"
6297 [(set_attr "type" "savew")])
6299 (define_expand "epilogue"
6304 sparc_flat_expand_epilogue (false);
6306 sparc_expand_epilogue (false);
6309 (define_expand "sibcall_epilogue"
6314 sparc_flat_expand_epilogue (false);
6316 sparc_expand_epilogue (false);
6320 (define_expand "eh_return"
6321 [(use (match_operand 0 "general_operand" ""))]
6324 emit_move_insn (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), operands[0]);
6325 emit_jump_insn (gen_eh_return_internal ());
6330 (define_insn_and_split "eh_return_internal"
6334 "epilogue_completed"
6338 sparc_flat_expand_epilogue (true);
6340 sparc_expand_epilogue (true);
6343 (define_expand "return"
6345 "sparc_can_use_return_insn_p ()"
6348 (define_insn "*return_internal"
6351 "* return output_return (insn);"
6352 [(set_attr "type" "return")
6353 (set (attr "length")
6354 (cond [(eq_attr "calls_eh_return" "true")
6355 (if_then_else (eq_attr "delayed_branch" "true")
6356 (if_then_else (ior (eq_attr "isa" "v9")
6357 (eq_attr "flat" "true"))
6360 (if_then_else (eq_attr "flat" "true")
6363 (ior (eq_attr "leaf_function" "true") (eq_attr "flat" "true"))
6364 (if_then_else (eq_attr "empty_delay_slot" "true")
6367 (eq_attr "empty_delay_slot" "true")
6368 (if_then_else (eq_attr "delayed_branch" "true")
6373 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6374 ;; all of memory. This blocks insns from being moved across this point.
6376 (define_insn "blockage"
6377 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6380 [(set_attr "length" "0")])
6382 (define_expand "probe_stack"
6383 [(set (match_operand 0 "memory_operand" "") (const_int 0))]
6387 = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
6390 (define_insn "probe_stack_range<P:mode>"
6391 [(set (match_operand:P 0 "register_operand" "=r")
6392 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6393 (match_operand:P 2 "register_operand" "r")]
6394 UNSPECV_PROBE_STACK_RANGE))]
6396 "* return output_probe_stack_range (operands[0], operands[2]);"
6397 [(set_attr "type" "multi")])
6399 ;; Prepare to return any type including a structure value.
6401 (define_expand "untyped_return"
6402 [(match_operand:BLK 0 "memory_operand" "")
6403 (match_operand 1 "" "")]
6406 rtx valreg1 = gen_rtx_REG (DImode, 24);
6407 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6408 rtx result = operands[0];
6410 if (! TARGET_ARCH64)
6412 rtx rtnreg = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
6413 rtx value = gen_reg_rtx (SImode);
6415 /* Fetch the instruction where we will return to and see if it's an unimp
6416 instruction (the most significant 10 bits will be zero). If so,
6417 update the return address to skip the unimp instruction. */
6418 emit_move_insn (value,
6419 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
6420 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6421 emit_insn (gen_update_return (rtnreg, value));
6424 /* Reload the function value registers. */
6425 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6426 emit_move_insn (valreg2,
6427 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6429 /* Put USE insns before the return. */
6433 /* Construct the return. */
6434 expand_naked_return ();
6439 ;; Adjust the return address conditionally. If the value of op1 is equal
6440 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6441 ;; This is technically *half* the check required by the 32-bit SPARC
6442 ;; psABI. This check only ensures that an "unimp" insn was written by
6443 ;; the caller, but doesn't check to see if the expected size matches
6444 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6445 ;; only used by the above code "untyped_return".
6447 (define_insn "update_return"
6448 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6449 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6452 if (flag_delayed_branch)
6453 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6455 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6457 [(set (attr "type") (const_string "multi"))
6458 (set (attr "length")
6459 (if_then_else (eq_attr "delayed_branch" "true")
6468 (define_expand "indirect_jump"
6469 [(set (pc) (match_operand 0 "address_operand" "p"))]
6473 (define_insn "*branch_sp32"
6474 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6477 [(set_attr "type" "uncond_branch")])
6479 (define_insn "*branch_sp64"
6480 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6483 [(set_attr "type" "uncond_branch")])
6485 (define_expand "save_stack_nonlocal"
6486 [(set (match_operand 0 "memory_operand" "")
6487 (match_operand 1 "register_operand" ""))
6488 (set (match_dup 2) (match_dup 3))]
6491 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
6492 operands[2] = adjust_address_nv (operands[0], Pmode, GET_MODE_SIZE (Pmode));
6493 operands[3] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6496 (define_expand "restore_stack_nonlocal"
6497 [(set (match_operand 0 "register_operand" "")
6498 (match_operand 1 "memory_operand" ""))]
6501 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
6504 (define_expand "nonlocal_goto"
6505 [(match_operand 0 "general_operand" "")
6506 (match_operand 1 "general_operand" "")
6507 (match_operand 2 "memory_operand" "")
6508 (match_operand 3 "memory_operand" "")]
6511 rtx r_label = copy_to_reg (operands[1]);
6512 rtx r_sp = adjust_address_nv (operands[2], Pmode, 0);
6513 rtx r_fp = operands[3];
6514 rtx r_i7 = adjust_address_nv (operands[2], Pmode, GET_MODE_SIZE (Pmode));
6516 /* We need to flush all the register windows so that their contents will
6517 be re-synchronized by the restore insn of the target function. */
6519 emit_insn (gen_flush_register_windows ());
6521 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
6522 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
6524 /* Restore frame pointer for containing function. */
6525 emit_move_insn (hard_frame_pointer_rtx, r_fp);
6526 emit_stack_restore (SAVE_NONLOCAL, r_sp);
6528 /* USE of hard_frame_pointer_rtx added for consistency;
6529 not clear if really needed. */
6530 emit_use (hard_frame_pointer_rtx);
6531 emit_use (stack_pointer_rtx);
6533 /* We need to smuggle the load of %i7 as it is a fixed register. */
6534 emit_jump_insn (gen_nonlocal_goto_internal (r_label, r_i7));
6539 (define_insn "nonlocal_goto_internal"
6540 [(unspec_volatile [(match_operand 0 "register_operand" "r")
6541 (match_operand 1 "memory_operand" "m")] UNSPECV_GOTO)]
6542 "GET_MODE (operands[0]) == Pmode && GET_MODE (operands[1]) == Pmode"
6544 if (flag_delayed_branch)
6547 return "jmp\t%0\n\t ldx\t%1, %%i7";
6549 return "jmp\t%0\n\t ld\t%1, %%i7";
6554 return "ldx\t%1, %%i7\n\tjmp\t%0\n\t nop";
6556 return "ld\t%1, %%i7\n\tjmp\t%0\n\t nop";
6559 [(set (attr "type") (const_string "multi"))
6560 (set (attr "length")
6561 (if_then_else (eq_attr "delayed_branch" "true")
6565 (define_expand "builtin_setjmp_receiver"
6566 [(label_ref (match_operand 0 "" ""))]
6569 load_got_register ();
6573 ;; Special insn to flush register windows.
6575 (define_insn "flush_register_windows"
6576 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
6578 { return TARGET_V9 ? "flushw" : "ta\t3"; }
6579 [(set_attr "type" "flushw")])
6581 ;; Special pattern for the FLUSH instruction.
6583 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
6584 ; of the define_insn otherwise missing a mode. We make "flush", aka
6585 ; gen_flush, the default one since sparc_initialize_trampoline uses
6586 ; it on SImode mem values.
6588 (define_insn "flush"
6589 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6591 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6592 [(set_attr "type" "iflush")])
6594 (define_insn "flushdi"
6595 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6597 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6598 [(set_attr "type" "iflush")])
6601 ;; Find first set instructions.
6603 ;; The scan instruction searches from the most significant bit while ffs
6604 ;; searches from the least significant bit. The bit index and treatment of
6605 ;; zero also differ. It takes at least 7 instructions to get the proper
6606 ;; result. Here is an obvious 8 instruction sequence.
6609 (define_insn "ffssi2"
6610 [(set (match_operand:SI 0 "register_operand" "=&r")
6611 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
6612 (clobber (match_scratch:SI 2 "=&r"))]
6613 "TARGET_SPARCLITE || TARGET_SPARCLET"
6615 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";
6617 [(set_attr "type" "multi")
6618 (set_attr "length" "8")])
6620 ;; ??? This should be a define expand, so that the extra instruction have
6621 ;; a chance of being optimized away.
6623 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
6624 ;; does, but no one uses that and we don't have a switch for it.
6626 ;(define_insn "ffsdi2"
6627 ; [(set (match_operand:DI 0 "register_operand" "=&r")
6628 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
6629 ; (clobber (match_scratch:DI 2 "=&r"))]
6631 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
6632 ; [(set_attr "type" "multi")
6633 ; (set_attr "length" "4")])
6637 ;; Peepholes go at the end.
6639 ;; Optimize consecutive loads or stores into ldd and std when possible.
6640 ;; The conditions in which we do this are very restricted and are
6641 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
6644 [(set (match_operand:SI 0 "memory_operand" "")
6646 (set (match_operand:SI 1 "memory_operand" "")
6649 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
6652 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
6655 [(set (match_operand:SI 0 "memory_operand" "")
6657 (set (match_operand:SI 1 "memory_operand" "")
6660 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
6663 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
6666 [(set (match_operand:SI 0 "register_operand" "")
6667 (match_operand:SI 1 "memory_operand" ""))
6668 (set (match_operand:SI 2 "register_operand" "")
6669 (match_operand:SI 3 "memory_operand" ""))]
6670 "registers_ok_for_ldd_peep (operands[0], operands[2])
6671 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6674 "operands[1] = widen_memory_access (operands[1], DImode, 0);
6675 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
6678 [(set (match_operand:SI 0 "memory_operand" "")
6679 (match_operand:SI 1 "register_operand" ""))
6680 (set (match_operand:SI 2 "memory_operand" "")
6681 (match_operand:SI 3 "register_operand" ""))]
6682 "registers_ok_for_ldd_peep (operands[1], operands[3])
6683 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6686 "operands[0] = widen_memory_access (operands[0], DImode, 0);
6687 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
6690 [(set (match_operand:SF 0 "register_operand" "")
6691 (match_operand:SF 1 "memory_operand" ""))
6692 (set (match_operand:SF 2 "register_operand" "")
6693 (match_operand:SF 3 "memory_operand" ""))]
6694 "registers_ok_for_ldd_peep (operands[0], operands[2])
6695 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6698 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
6699 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
6702 [(set (match_operand:SF 0 "memory_operand" "")
6703 (match_operand:SF 1 "register_operand" ""))
6704 (set (match_operand:SF 2 "memory_operand" "")
6705 (match_operand:SF 3 "register_operand" ""))]
6706 "registers_ok_for_ldd_peep (operands[1], operands[3])
6707 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6710 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
6711 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
6714 [(set (match_operand:SI 0 "register_operand" "")
6715 (match_operand:SI 1 "memory_operand" ""))
6716 (set (match_operand:SI 2 "register_operand" "")
6717 (match_operand:SI 3 "memory_operand" ""))]
6718 "registers_ok_for_ldd_peep (operands[2], operands[0])
6719 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6722 "operands[3] = widen_memory_access (operands[3], DImode, 0);
6723 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
6726 [(set (match_operand:SI 0 "memory_operand" "")
6727 (match_operand:SI 1 "register_operand" ""))
6728 (set (match_operand:SI 2 "memory_operand" "")
6729 (match_operand:SI 3 "register_operand" ""))]
6730 "registers_ok_for_ldd_peep (operands[3], operands[1])
6731 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6734 "operands[2] = widen_memory_access (operands[2], DImode, 0);
6735 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
6739 [(set (match_operand:SF 0 "register_operand" "")
6740 (match_operand:SF 1 "memory_operand" ""))
6741 (set (match_operand:SF 2 "register_operand" "")
6742 (match_operand:SF 3 "memory_operand" ""))]
6743 "registers_ok_for_ldd_peep (operands[2], operands[0])
6744 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6747 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
6748 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
6751 [(set (match_operand:SF 0 "memory_operand" "")
6752 (match_operand:SF 1 "register_operand" ""))
6753 (set (match_operand:SF 2 "memory_operand" "")
6754 (match_operand:SF 3 "register_operand" ""))]
6755 "registers_ok_for_ldd_peep (operands[3], operands[1])
6756 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6759 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
6760 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
6762 ;; Optimize the case of following a reg-reg move with a test
6763 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
6764 ;; This can result from a float to fix conversion.
6767 [(set (match_operand:SI 0 "register_operand" "")
6768 (match_operand:SI 1 "register_operand" ""))
6770 (compare:CC (match_operand:SI 2 "register_operand" "")
6772 "(rtx_equal_p (operands[2], operands[0])
6773 || rtx_equal_p (operands[2], operands[1]))
6774 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6775 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6776 [(parallel [(set (match_dup 0) (match_dup 1))
6778 (compare:CC (match_dup 1) (const_int 0)))])]
6782 [(set (match_operand:DI 0 "register_operand" "")
6783 (match_operand:DI 1 "register_operand" ""))
6785 (compare:CCX (match_operand:DI 2 "register_operand" "")
6788 && (rtx_equal_p (operands[2], operands[0])
6789 || rtx_equal_p (operands[2], operands[1]))
6790 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6791 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6792 [(parallel [(set (match_dup 0) (match_dup 1))
6794 (compare:CCX (match_dup 1) (const_int 0)))])]
6798 ;; Prefetch instructions.
6800 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
6801 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
6802 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
6804 (define_expand "prefetch"
6805 [(match_operand 0 "address_operand" "")
6806 (match_operand 1 "const_int_operand" "")
6807 (match_operand 2 "const_int_operand" "")]
6811 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
6813 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
6817 (define_insn "prefetch_64"
6818 [(prefetch (match_operand:DI 0 "address_operand" "p")
6819 (match_operand:DI 1 "const_int_operand" "n")
6820 (match_operand:DI 2 "const_int_operand" "n"))]
6823 static const char * const prefetch_instr[2][2] = {
6825 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
6826 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
6829 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
6830 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
6833 int read_or_write = INTVAL (operands[1]);
6834 int locality = INTVAL (operands[2]);
6836 gcc_assert (read_or_write == 0 || read_or_write == 1);
6837 gcc_assert (locality >= 0 && locality < 4);
6838 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
6840 [(set_attr "type" "load")])
6842 (define_insn "prefetch_32"
6843 [(prefetch (match_operand:SI 0 "address_operand" "p")
6844 (match_operand:SI 1 "const_int_operand" "n")
6845 (match_operand:SI 2 "const_int_operand" "n"))]
6848 static const char * const prefetch_instr[2][2] = {
6850 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
6851 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
6854 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
6855 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
6858 int read_or_write = INTVAL (operands[1]);
6859 int locality = INTVAL (operands[2]);
6861 gcc_assert (read_or_write == 0 || read_or_write == 1);
6862 gcc_assert (locality >= 0 && locality < 4);
6863 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
6865 [(set_attr "type" "load")])
6868 ;; Trap instructions.
6871 [(trap_if (const_int 1) (const_int 5))]
6874 [(set_attr "type" "trap")])
6876 (define_expand "ctrapsi4"
6877 [(trap_if (match_operator 0 "noov_compare_operator"
6878 [(match_operand:SI 1 "compare_operand" "")
6879 (match_operand:SI 2 "arith_operand" "")])
6880 (match_operand 3 ""))]
6882 "operands[1] = gen_compare_reg (operands[0]);
6883 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
6885 operands[2] = const0_rtx;")
6887 (define_expand "ctrapdi4"
6888 [(trap_if (match_operator 0 "noov_compare_operator"
6889 [(match_operand:DI 1 "compare_operand" "")
6890 (match_operand:DI 2 "arith_operand" "")])
6891 (match_operand 3 ""))]
6893 "operands[1] = gen_compare_reg (operands[0]);
6894 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
6896 operands[2] = const0_rtx;")
6900 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC 100) (const_int 0)])
6901 (match_operand:SI 1 "arith_operand" "rM"))]
6905 return "t%C0\t%%icc, %1";
6909 [(set_attr "type" "trap")])
6912 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX 100) (const_int 0)])
6913 (match_operand:SI 1 "arith_operand" "rM"))]
6916 [(set_attr "type" "trap")])
6919 ;; TLS support instructions.
6921 (define_insn "tgd_hi22"
6922 [(set (match_operand:SI 0 "register_operand" "=r")
6923 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
6926 "sethi\\t%%tgd_hi22(%a1), %0")
6928 (define_insn "tgd_lo10"
6929 [(set (match_operand:SI 0 "register_operand" "=r")
6930 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
6931 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
6934 "add\\t%1, %%tgd_lo10(%a2), %0")
6936 (define_insn "tgd_add32"
6937 [(set (match_operand:SI 0 "register_operand" "=r")
6938 (plus:SI (match_operand:SI 1 "register_operand" "r")
6939 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
6940 (match_operand 3 "tgd_symbolic_operand" "")]
6942 "TARGET_TLS && TARGET_ARCH32"
6943 "add\\t%1, %2, %0, %%tgd_add(%a3)")
6945 (define_insn "tgd_add64"
6946 [(set (match_operand:DI 0 "register_operand" "=r")
6947 (plus:DI (match_operand:DI 1 "register_operand" "r")
6948 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
6949 (match_operand 3 "tgd_symbolic_operand" "")]
6951 "TARGET_TLS && TARGET_ARCH64"
6952 "add\\t%1, %2, %0, %%tgd_add(%a3)")
6954 (define_insn "tgd_call32"
6955 [(set (match_operand 0 "register_operand" "=r")
6956 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
6957 (match_operand 2 "tgd_symbolic_operand" "")]
6959 (match_operand 3 "" "")))
6960 (clobber (reg:SI 15))]
6961 "TARGET_TLS && TARGET_ARCH32"
6962 "call\t%a1, %%tgd_call(%a2)%#"
6963 [(set_attr "type" "call")])
6965 (define_insn "tgd_call64"
6966 [(set (match_operand 0 "register_operand" "=r")
6967 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
6968 (match_operand 2 "tgd_symbolic_operand" "")]
6970 (match_operand 3 "" "")))
6971 (clobber (reg:DI 15))]
6972 "TARGET_TLS && TARGET_ARCH64"
6973 "call\t%a1, %%tgd_call(%a2)%#"
6974 [(set_attr "type" "call")])
6976 (define_insn "tldm_hi22"
6977 [(set (match_operand:SI 0 "register_operand" "=r")
6978 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
6980 "sethi\\t%%tldm_hi22(%&), %0")
6982 (define_insn "tldm_lo10"
6983 [(set (match_operand:SI 0 "register_operand" "=r")
6984 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
6985 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
6987 "add\\t%1, %%tldm_lo10(%&), %0")
6989 (define_insn "tldm_add32"
6990 [(set (match_operand:SI 0 "register_operand" "=r")
6991 (plus:SI (match_operand:SI 1 "register_operand" "r")
6992 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
6994 "TARGET_TLS && TARGET_ARCH32"
6995 "add\\t%1, %2, %0, %%tldm_add(%&)")
6997 (define_insn "tldm_add64"
6998 [(set (match_operand:DI 0 "register_operand" "=r")
6999 (plus:DI (match_operand:DI 1 "register_operand" "r")
7000 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7002 "TARGET_TLS && TARGET_ARCH64"
7003 "add\\t%1, %2, %0, %%tldm_add(%&)")
7005 (define_insn "tldm_call32"
7006 [(set (match_operand 0 "register_operand" "=r")
7007 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7009 (match_operand 2 "" "")))
7010 (clobber (reg:SI 15))]
7011 "TARGET_TLS && TARGET_ARCH32"
7012 "call\t%a1, %%tldm_call(%&)%#"
7013 [(set_attr "type" "call")])
7015 (define_insn "tldm_call64"
7016 [(set (match_operand 0 "register_operand" "=r")
7017 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7019 (match_operand 2 "" "")))
7020 (clobber (reg:DI 15))]
7021 "TARGET_TLS && TARGET_ARCH64"
7022 "call\t%a1, %%tldm_call(%&)%#"
7023 [(set_attr "type" "call")])
7025 (define_insn "tldo_hix22"
7026 [(set (match_operand:SI 0 "register_operand" "=r")
7027 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7030 "sethi\\t%%tldo_hix22(%a1), %0")
7032 (define_insn "tldo_lox10"
7033 [(set (match_operand:SI 0 "register_operand" "=r")
7034 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7035 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7038 "xor\\t%1, %%tldo_lox10(%a2), %0")
7040 (define_insn "tldo_add32"
7041 [(set (match_operand:SI 0 "register_operand" "=r")
7042 (plus:SI (match_operand:SI 1 "register_operand" "r")
7043 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7044 (match_operand 3 "tld_symbolic_operand" "")]
7046 "TARGET_TLS && TARGET_ARCH32"
7047 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7049 (define_insn "tldo_add64"
7050 [(set (match_operand:DI 0 "register_operand" "=r")
7051 (plus:DI (match_operand:DI 1 "register_operand" "r")
7052 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7053 (match_operand 3 "tld_symbolic_operand" "")]
7055 "TARGET_TLS && TARGET_ARCH64"
7056 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7058 (define_insn "tie_hi22"
7059 [(set (match_operand:SI 0 "register_operand" "=r")
7060 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7063 "sethi\\t%%tie_hi22(%a1), %0")
7065 (define_insn "tie_lo10"
7066 [(set (match_operand:SI 0 "register_operand" "=r")
7067 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7068 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7071 "add\\t%1, %%tie_lo10(%a2), %0")
7073 (define_insn "tie_ld32"
7074 [(set (match_operand:SI 0 "register_operand" "=r")
7075 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7076 (match_operand:SI 2 "register_operand" "r")
7077 (match_operand 3 "tie_symbolic_operand" "")]
7079 "TARGET_TLS && TARGET_ARCH32"
7080 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7081 [(set_attr "type" "load")])
7083 (define_insn "tie_ld64"
7084 [(set (match_operand:DI 0 "register_operand" "=r")
7085 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7086 (match_operand:SI 2 "register_operand" "r")
7087 (match_operand 3 "tie_symbolic_operand" "")]
7089 "TARGET_TLS && TARGET_ARCH64"
7090 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7091 [(set_attr "type" "load")])
7093 (define_insn "tie_add32"
7094 [(set (match_operand:SI 0 "register_operand" "=r")
7095 (plus:SI (match_operand:SI 1 "register_operand" "r")
7096 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7097 (match_operand 3 "tie_symbolic_operand" "")]
7099 "TARGET_SUN_TLS && TARGET_ARCH32"
7100 "add\\t%1, %2, %0, %%tie_add(%a3)")
7102 (define_insn "tie_add64"
7103 [(set (match_operand:DI 0 "register_operand" "=r")
7104 (plus:DI (match_operand:DI 1 "register_operand" "r")
7105 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7106 (match_operand 3 "tie_symbolic_operand" "")]
7108 "TARGET_SUN_TLS && TARGET_ARCH64"
7109 "add\\t%1, %2, %0, %%tie_add(%a3)")
7111 (define_insn "tle_hix22_sp32"
7112 [(set (match_operand:SI 0 "register_operand" "=r")
7113 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7115 "TARGET_TLS && TARGET_ARCH32"
7116 "sethi\\t%%tle_hix22(%a1), %0")
7118 (define_insn "tle_lox10_sp32"
7119 [(set (match_operand:SI 0 "register_operand" "=r")
7120 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7121 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7123 "TARGET_TLS && TARGET_ARCH32"
7124 "xor\\t%1, %%tle_lox10(%a2), %0")
7126 (define_insn "tle_hix22_sp64"
7127 [(set (match_operand:DI 0 "register_operand" "=r")
7128 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7130 "TARGET_TLS && TARGET_ARCH64"
7131 "sethi\\t%%tle_hix22(%a1), %0")
7133 (define_insn "tle_lox10_sp64"
7134 [(set (match_operand:DI 0 "register_operand" "=r")
7135 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7136 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7138 "TARGET_TLS && TARGET_ARCH64"
7139 "xor\\t%1, %%tle_lox10(%a2), %0")
7141 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7142 (define_insn "*tldo_ldub_sp32"
7143 [(set (match_operand:QI 0 "register_operand" "=r")
7144 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7145 (match_operand 3 "tld_symbolic_operand" "")]
7147 (match_operand:SI 1 "register_operand" "r"))))]
7148 "TARGET_TLS && TARGET_ARCH32"
7149 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7150 [(set_attr "type" "load")
7151 (set_attr "us3load_type" "3cycle")])
7153 (define_insn "*tldo_ldub1_sp32"
7154 [(set (match_operand:HI 0 "register_operand" "=r")
7155 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7156 (match_operand 3 "tld_symbolic_operand" "")]
7158 (match_operand:SI 1 "register_operand" "r")))))]
7159 "TARGET_TLS && TARGET_ARCH32"
7160 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7161 [(set_attr "type" "load")
7162 (set_attr "us3load_type" "3cycle")])
7164 (define_insn "*tldo_ldub2_sp32"
7165 [(set (match_operand:SI 0 "register_operand" "=r")
7166 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7167 (match_operand 3 "tld_symbolic_operand" "")]
7169 (match_operand:SI 1 "register_operand" "r")))))]
7170 "TARGET_TLS && TARGET_ARCH32"
7171 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7172 [(set_attr "type" "load")
7173 (set_attr "us3load_type" "3cycle")])
7175 (define_insn "*tldo_ldsb1_sp32"
7176 [(set (match_operand:HI 0 "register_operand" "=r")
7177 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7178 (match_operand 3 "tld_symbolic_operand" "")]
7180 (match_operand:SI 1 "register_operand" "r")))))]
7181 "TARGET_TLS && TARGET_ARCH32"
7182 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7183 [(set_attr "type" "sload")
7184 (set_attr "us3load_type" "3cycle")])
7186 (define_insn "*tldo_ldsb2_sp32"
7187 [(set (match_operand:SI 0 "register_operand" "=r")
7188 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7189 (match_operand 3 "tld_symbolic_operand" "")]
7191 (match_operand:SI 1 "register_operand" "r")))))]
7192 "TARGET_TLS && TARGET_ARCH32"
7193 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7194 [(set_attr "type" "sload")
7195 (set_attr "us3load_type" "3cycle")])
7197 (define_insn "*tldo_ldub_sp64"
7198 [(set (match_operand:QI 0 "register_operand" "=r")
7199 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7200 (match_operand 3 "tld_symbolic_operand" "")]
7202 (match_operand:DI 1 "register_operand" "r"))))]
7203 "TARGET_TLS && TARGET_ARCH64"
7204 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7205 [(set_attr "type" "load")
7206 (set_attr "us3load_type" "3cycle")])
7208 (define_insn "*tldo_ldub1_sp64"
7209 [(set (match_operand:HI 0 "register_operand" "=r")
7210 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7211 (match_operand 3 "tld_symbolic_operand" "")]
7213 (match_operand:DI 1 "register_operand" "r")))))]
7214 "TARGET_TLS && TARGET_ARCH64"
7215 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7216 [(set_attr "type" "load")
7217 (set_attr "us3load_type" "3cycle")])
7219 (define_insn "*tldo_ldub2_sp64"
7220 [(set (match_operand:SI 0 "register_operand" "=r")
7221 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7222 (match_operand 3 "tld_symbolic_operand" "")]
7224 (match_operand:DI 1 "register_operand" "r")))))]
7225 "TARGET_TLS && TARGET_ARCH64"
7226 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7227 [(set_attr "type" "load")
7228 (set_attr "us3load_type" "3cycle")])
7230 (define_insn "*tldo_ldub3_sp64"
7231 [(set (match_operand:DI 0 "register_operand" "=r")
7232 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7233 (match_operand 3 "tld_symbolic_operand" "")]
7235 (match_operand:DI 1 "register_operand" "r")))))]
7236 "TARGET_TLS && TARGET_ARCH64"
7237 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7238 [(set_attr "type" "load")
7239 (set_attr "us3load_type" "3cycle")])
7241 (define_insn "*tldo_ldsb1_sp64"
7242 [(set (match_operand:HI 0 "register_operand" "=r")
7243 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7244 (match_operand 3 "tld_symbolic_operand" "")]
7246 (match_operand:DI 1 "register_operand" "r")))))]
7247 "TARGET_TLS && TARGET_ARCH64"
7248 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7249 [(set_attr "type" "sload")
7250 (set_attr "us3load_type" "3cycle")])
7252 (define_insn "*tldo_ldsb2_sp64"
7253 [(set (match_operand:SI 0 "register_operand" "=r")
7254 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7255 (match_operand 3 "tld_symbolic_operand" "")]
7257 (match_operand:DI 1 "register_operand" "r")))))]
7258 "TARGET_TLS && TARGET_ARCH64"
7259 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7260 [(set_attr "type" "sload")
7261 (set_attr "us3load_type" "3cycle")])
7263 (define_insn "*tldo_ldsb3_sp64"
7264 [(set (match_operand:DI 0 "register_operand" "=r")
7265 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7266 (match_operand 3 "tld_symbolic_operand" "")]
7268 (match_operand:DI 1 "register_operand" "r")))))]
7269 "TARGET_TLS && TARGET_ARCH64"
7270 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7271 [(set_attr "type" "sload")
7272 (set_attr "us3load_type" "3cycle")])
7274 (define_insn "*tldo_lduh_sp32"
7275 [(set (match_operand:HI 0 "register_operand" "=r")
7276 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7277 (match_operand 3 "tld_symbolic_operand" "")]
7279 (match_operand:SI 1 "register_operand" "r"))))]
7280 "TARGET_TLS && TARGET_ARCH32"
7281 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7282 [(set_attr "type" "load")
7283 (set_attr "us3load_type" "3cycle")])
7285 (define_insn "*tldo_lduh1_sp32"
7286 [(set (match_operand:SI 0 "register_operand" "=r")
7287 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7288 (match_operand 3 "tld_symbolic_operand" "")]
7290 (match_operand:SI 1 "register_operand" "r")))))]
7291 "TARGET_TLS && TARGET_ARCH32"
7292 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7293 [(set_attr "type" "load")
7294 (set_attr "us3load_type" "3cycle")])
7296 (define_insn "*tldo_ldsh1_sp32"
7297 [(set (match_operand:SI 0 "register_operand" "=r")
7298 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7299 (match_operand 3 "tld_symbolic_operand" "")]
7301 (match_operand:SI 1 "register_operand" "r")))))]
7302 "TARGET_TLS && TARGET_ARCH32"
7303 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7304 [(set_attr "type" "sload")
7305 (set_attr "us3load_type" "3cycle")])
7307 (define_insn "*tldo_lduh_sp64"
7308 [(set (match_operand:HI 0 "register_operand" "=r")
7309 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7310 (match_operand 3 "tld_symbolic_operand" "")]
7312 (match_operand:DI 1 "register_operand" "r"))))]
7313 "TARGET_TLS && TARGET_ARCH64"
7314 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7315 [(set_attr "type" "load")
7316 (set_attr "us3load_type" "3cycle")])
7318 (define_insn "*tldo_lduh1_sp64"
7319 [(set (match_operand:SI 0 "register_operand" "=r")
7320 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7321 (match_operand 3 "tld_symbolic_operand" "")]
7323 (match_operand:DI 1 "register_operand" "r")))))]
7324 "TARGET_TLS && TARGET_ARCH64"
7325 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7326 [(set_attr "type" "load")
7327 (set_attr "us3load_type" "3cycle")])
7329 (define_insn "*tldo_lduh2_sp64"
7330 [(set (match_operand:DI 0 "register_operand" "=r")
7331 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7332 (match_operand 3 "tld_symbolic_operand" "")]
7334 (match_operand:DI 1 "register_operand" "r")))))]
7335 "TARGET_TLS && TARGET_ARCH64"
7336 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7337 [(set_attr "type" "load")
7338 (set_attr "us3load_type" "3cycle")])
7340 (define_insn "*tldo_ldsh1_sp64"
7341 [(set (match_operand:SI 0 "register_operand" "=r")
7342 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7343 (match_operand 3 "tld_symbolic_operand" "")]
7345 (match_operand:DI 1 "register_operand" "r")))))]
7346 "TARGET_TLS && TARGET_ARCH64"
7347 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7348 [(set_attr "type" "sload")
7349 (set_attr "us3load_type" "3cycle")])
7351 (define_insn "*tldo_ldsh2_sp64"
7352 [(set (match_operand:DI 0 "register_operand" "=r")
7353 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7354 (match_operand 3 "tld_symbolic_operand" "")]
7356 (match_operand:DI 1 "register_operand" "r")))))]
7357 "TARGET_TLS && TARGET_ARCH64"
7358 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7359 [(set_attr "type" "sload")
7360 (set_attr "us3load_type" "3cycle")])
7362 (define_insn "*tldo_lduw_sp32"
7363 [(set (match_operand:SI 0 "register_operand" "=r")
7364 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7365 (match_operand 3 "tld_symbolic_operand" "")]
7367 (match_operand:SI 1 "register_operand" "r"))))]
7368 "TARGET_TLS && TARGET_ARCH32"
7369 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7370 [(set_attr "type" "load")])
7372 (define_insn "*tldo_lduw_sp64"
7373 [(set (match_operand:SI 0 "register_operand" "=r")
7374 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7375 (match_operand 3 "tld_symbolic_operand" "")]
7377 (match_operand:DI 1 "register_operand" "r"))))]
7378 "TARGET_TLS && TARGET_ARCH64"
7379 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7380 [(set_attr "type" "load")])
7382 (define_insn "*tldo_lduw1_sp64"
7383 [(set (match_operand:DI 0 "register_operand" "=r")
7384 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7385 (match_operand 3 "tld_symbolic_operand" "")]
7387 (match_operand:DI 1 "register_operand" "r")))))]
7388 "TARGET_TLS && TARGET_ARCH64"
7389 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7390 [(set_attr "type" "load")])
7392 (define_insn "*tldo_ldsw1_sp64"
7393 [(set (match_operand:DI 0 "register_operand" "=r")
7394 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7395 (match_operand 3 "tld_symbolic_operand" "")]
7397 (match_operand:DI 1 "register_operand" "r")))))]
7398 "TARGET_TLS && TARGET_ARCH64"
7399 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7400 [(set_attr "type" "sload")
7401 (set_attr "us3load_type" "3cycle")])
7403 (define_insn "*tldo_ldx_sp64"
7404 [(set (match_operand:DI 0 "register_operand" "=r")
7405 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7406 (match_operand 3 "tld_symbolic_operand" "")]
7408 (match_operand:DI 1 "register_operand" "r"))))]
7409 "TARGET_TLS && TARGET_ARCH64"
7410 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7411 [(set_attr "type" "load")])
7413 (define_insn "*tldo_stb_sp32"
7414 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7415 (match_operand 3 "tld_symbolic_operand" "")]
7417 (match_operand:SI 1 "register_operand" "r")))
7418 (match_operand:QI 0 "register_operand" "=r"))]
7419 "TARGET_TLS && TARGET_ARCH32"
7420 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7421 [(set_attr "type" "store")])
7423 (define_insn "*tldo_stb_sp64"
7424 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7425 (match_operand 3 "tld_symbolic_operand" "")]
7427 (match_operand:DI 1 "register_operand" "r")))
7428 (match_operand:QI 0 "register_operand" "=r"))]
7429 "TARGET_TLS && TARGET_ARCH64"
7430 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7431 [(set_attr "type" "store")])
7433 (define_insn "*tldo_sth_sp32"
7434 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7435 (match_operand 3 "tld_symbolic_operand" "")]
7437 (match_operand:SI 1 "register_operand" "r")))
7438 (match_operand:HI 0 "register_operand" "=r"))]
7439 "TARGET_TLS && TARGET_ARCH32"
7440 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7441 [(set_attr "type" "store")])
7443 (define_insn "*tldo_sth_sp64"
7444 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7445 (match_operand 3 "tld_symbolic_operand" "")]
7447 (match_operand:DI 1 "register_operand" "r")))
7448 (match_operand:HI 0 "register_operand" "=r"))]
7449 "TARGET_TLS && TARGET_ARCH64"
7450 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7451 [(set_attr "type" "store")])
7453 (define_insn "*tldo_stw_sp32"
7454 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7455 (match_operand 3 "tld_symbolic_operand" "")]
7457 (match_operand:SI 1 "register_operand" "r")))
7458 (match_operand:SI 0 "register_operand" "=r"))]
7459 "TARGET_TLS && TARGET_ARCH32"
7460 "st\t%0, [%1 + %2], %%tldo_add(%3)"
7461 [(set_attr "type" "store")])
7463 (define_insn "*tldo_stw_sp64"
7464 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7465 (match_operand 3 "tld_symbolic_operand" "")]
7467 (match_operand:DI 1 "register_operand" "r")))
7468 (match_operand:SI 0 "register_operand" "=r"))]
7469 "TARGET_TLS && TARGET_ARCH64"
7470 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7471 [(set_attr "type" "store")])
7473 (define_insn "*tldo_stx_sp64"
7474 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7475 (match_operand 3 "tld_symbolic_operand" "")]
7477 (match_operand:DI 1 "register_operand" "r")))
7478 (match_operand:DI 0 "register_operand" "=r"))]
7479 "TARGET_TLS && TARGET_ARCH64"
7480 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7481 [(set_attr "type" "store")])
7484 ;; Stack protector instructions.
7486 (define_expand "stack_protect_set"
7487 [(match_operand 0 "memory_operand" "")
7488 (match_operand 1 "memory_operand" "")]
7491 #ifdef TARGET_THREAD_SSP_OFFSET
7492 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7493 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7494 operands[1] = gen_rtx_MEM (Pmode, addr);
7497 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7499 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7503 (define_insn "stack_protect_setsi"
7504 [(set (match_operand:SI 0 "memory_operand" "=m")
7505 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7506 (set (match_scratch:SI 2 "=&r") (const_int 0))]
7508 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
7509 [(set_attr "type" "multi")
7510 (set_attr "length" "3")])
7512 (define_insn "stack_protect_setdi"
7513 [(set (match_operand:DI 0 "memory_operand" "=m")
7514 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7515 (set (match_scratch:DI 2 "=&r") (const_int 0))]
7517 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
7518 [(set_attr "type" "multi")
7519 (set_attr "length" "3")])
7521 (define_expand "stack_protect_test"
7522 [(match_operand 0 "memory_operand" "")
7523 (match_operand 1 "memory_operand" "")
7524 (match_operand 2 "" "")]
7528 #ifdef TARGET_THREAD_SSP_OFFSET
7529 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7530 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7531 operands[1] = gen_rtx_MEM (Pmode, addr);
7535 result = gen_reg_rtx (Pmode);
7536 emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
7537 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7538 emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
7542 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7543 result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
7544 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7545 emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
7550 (define_insn "stack_protect_testsi"
7552 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
7553 (match_operand:SI 1 "memory_operand" "m")]
7555 (set (match_scratch:SI 3 "=r") (const_int 0))
7556 (clobber (match_scratch:SI 2 "=&r"))]
7558 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
7559 [(set_attr "type" "multi")
7560 (set_attr "length" "4")])
7562 (define_insn "stack_protect_testdi"
7563 [(set (match_operand:DI 0 "register_operand" "=&r")
7564 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7565 (match_operand:DI 2 "memory_operand" "m")]
7567 (set (match_scratch:DI 3 "=r") (const_int 0))]
7569 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
7570 [(set_attr "type" "multi")
7571 (set_attr "length" "4")])
7574 ;; Vector instructions.
7576 (define_insn "addv2si3"
7577 [(set (match_operand:V2SI 0 "register_operand" "=e")
7578 (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7579 (match_operand:V2SI 2 "register_operand" "e")))]
7581 "fpadd32\t%1, %2, %0"
7582 [(set_attr "type" "fga")
7583 (set_attr "fptype" "double")])
7585 (define_insn "addv4hi3"
7586 [(set (match_operand:V4HI 0 "register_operand" "=e")
7587 (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7588 (match_operand:V4HI 2 "register_operand" "e")))]
7590 "fpadd16\t%1, %2, %0"
7591 [(set_attr "type" "fga")
7592 (set_attr "fptype" "double")])
7594 ;; fpadd32s is emitted by the addsi3 pattern.
7596 (define_insn "addv2hi3"
7597 [(set (match_operand:V2HI 0 "register_operand" "=f")
7598 (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7599 (match_operand:V2HI 2 "register_operand" "f")))]
7601 "fpadd16s\t%1, %2, %0"
7602 [(set_attr "type" "fga")
7603 (set_attr "fptype" "single")])
7605 (define_insn "subv2si3"
7606 [(set (match_operand:V2SI 0 "register_operand" "=e")
7607 (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7608 (match_operand:V2SI 2 "register_operand" "e")))]
7610 "fpsub32\t%1, %2, %0"
7611 [(set_attr "type" "fga")
7612 (set_attr "fptype" "double")])
7614 (define_insn "subv4hi3"
7615 [(set (match_operand:V4HI 0 "register_operand" "=e")
7616 (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7617 (match_operand:V4HI 2 "register_operand" "e")))]
7619 "fpsub16\t%1, %2, %0"
7620 [(set_attr "type" "fga")
7621 (set_attr "fptype" "double")])
7623 ;; fpsub32s is emitted by the subsi3 pattern.
7625 (define_insn "subv2hi3"
7626 [(set (match_operand:V2HI 0 "register_operand" "=f")
7627 (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7628 (match_operand:V2HI 2 "register_operand" "f")))]
7630 "fpsub16s\t%1, %2, %0"
7631 [(set_attr "type" "fga")
7632 (set_attr "fptype" "single")])
7634 ;; All other logical instructions have integer equivalents so they
7635 ;; are defined together.
7637 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
7639 (define_insn "*nand<V64:mode>_vis"
7640 [(set (match_operand:V64 0 "register_operand" "=e")
7641 (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
7642 (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
7645 [(set_attr "type" "fga")
7646 (set_attr "fptype" "double")])
7648 (define_insn "*nand<V32:mode>_vis"
7649 [(set (match_operand:V32 0 "register_operand" "=f")
7650 (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
7651 (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
7653 "fnands\t%1, %2, %0"
7654 [(set_attr "type" "fga")
7655 (set_attr "fptype" "single")])
7657 ;; Hard to generate VIS instructions. We have builtins for these.
7659 (define_insn "fpack16_vis"
7660 [(set (match_operand:V4QI 0 "register_operand" "=f")
7661 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
7665 [(set_attr "type" "fga")
7666 (set_attr "fptype" "double")])
7668 (define_insn "fpackfix_vis"
7669 [(set (match_operand:V2HI 0 "register_operand" "=f")
7670 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
7674 [(set_attr "type" "fga")
7675 (set_attr "fptype" "double")])
7677 (define_insn "fpack32_vis"
7678 [(set (match_operand:V8QI 0 "register_operand" "=e")
7679 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
7680 (match_operand:V8QI 2 "register_operand" "e")]
7683 "fpack32\t%1, %2, %0"
7684 [(set_attr "type" "fga")
7685 (set_attr "fptype" "double")])
7687 (define_insn "fexpand_vis"
7688 [(set (match_operand:V4HI 0 "register_operand" "=e")
7689 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
7693 [(set_attr "type" "fga")
7694 (set_attr "fptype" "double")])
7696 ;; It may be possible to describe this operation as (1 indexed):
7697 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
7698 ;; 1,5,10,14,19,23,28,32)
7699 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
7700 ;; because vec_merge expects all the operands to be of the same type.
7701 (define_insn "fpmerge_vis"
7702 [(set (match_operand:V8QI 0 "register_operand" "=e")
7703 (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
7704 (match_operand:V4QI 2 "register_operand" "f")]
7707 "fpmerge\t%1, %2, %0"
7708 [(set_attr "type" "fga")
7709 (set_attr "fptype" "double")])
7711 ;; Partitioned multiply instructions
7712 (define_insn "fmul8x16_vis"
7713 [(set (match_operand:V4HI 0 "register_operand" "=e")
7714 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7715 (match_operand:V4HI 2 "register_operand" "e")))]
7717 "fmul8x16\t%1, %2, %0"
7718 [(set_attr "type" "fpmul")
7719 (set_attr "fptype" "double")])
7721 ;; Only one of the following two insns can be a multiply.
7722 (define_insn "fmul8x16au_vis"
7723 [(set (match_operand:V4HI 0 "register_operand" "=e")
7724 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7725 (match_operand:V2HI 2 "register_operand" "f")))]
7727 "fmul8x16au\t%1, %2, %0"
7728 [(set_attr "type" "fpmul")
7729 (set_attr "fptype" "double")])
7731 (define_insn "fmul8x16al_vis"
7732 [(set (match_operand:V4HI 0 "register_operand" "=e")
7733 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
7734 (match_operand:V2HI 2 "register_operand" "f")]
7737 "fmul8x16al\t%1, %2, %0"
7738 [(set_attr "type" "fpmul")
7739 (set_attr "fptype" "double")])
7741 ;; Only one of the following two insns can be a multiply.
7742 (define_insn "fmul8sux16_vis"
7743 [(set (match_operand:V4HI 0 "register_operand" "=e")
7744 (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
7745 (match_operand:V4HI 2 "register_operand" "e")))]
7747 "fmul8sux16\t%1, %2, %0"
7748 [(set_attr "type" "fpmul")
7749 (set_attr "fptype" "double")])
7751 (define_insn "fmul8ulx16_vis"
7752 [(set (match_operand:V4HI 0 "register_operand" "=e")
7753 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
7754 (match_operand:V4HI 2 "register_operand" "e")]
7757 "fmul8ulx16\t%1, %2, %0"
7758 [(set_attr "type" "fpmul")
7759 (set_attr "fptype" "double")])
7761 ;; Only one of the following two insns can be a multiply.
7762 (define_insn "fmuld8sux16_vis"
7763 [(set (match_operand:V2SI 0 "register_operand" "=e")
7764 (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
7765 (match_operand:V2HI 2 "register_operand" "f")))]
7767 "fmuld8sux16\t%1, %2, %0"
7768 [(set_attr "type" "fpmul")
7769 (set_attr "fptype" "double")])
7771 (define_insn "fmuld8ulx16_vis"
7772 [(set (match_operand:V2SI 0 "register_operand" "=e")
7773 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
7774 (match_operand:V2HI 2 "register_operand" "f")]
7777 "fmuld8ulx16\t%1, %2, %0"
7778 [(set_attr "type" "fpmul")
7779 (set_attr "fptype" "double")])
7781 ;; Using faligndata only makes sense after an alignaddr since the choice of
7782 ;; bytes to take out of each operand is dependent on the results of the last
7784 (define_insn "faligndata<V64I:mode>_vis"
7785 [(set (match_operand:V64I 0 "register_operand" "=e")
7786 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
7787 (match_operand:V64I 2 "register_operand" "e")]
7790 "faligndata\t%1, %2, %0"
7791 [(set_attr "type" "fga")
7792 (set_attr "fptype" "double")])
7794 (define_insn "alignaddr<P:mode>_vis"
7795 [(set (match_operand:P 0 "register_operand" "=r")
7796 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
7797 (match_operand:P 2 "register_or_zero_operand" "rJ")]
7800 "alignaddr\t%r1, %r2, %0")
7802 (define_insn "alignaddrl<P:mode>_vis"
7803 [(set (match_operand:P 0 "register_operand" "=r")
7804 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
7805 (match_operand:P 2 "register_or_zero_operand" "rJ")]
7806 UNSPEC_ALIGNADDRL))]
7808 "alignaddrl\t%r1, %r2, %0")
7810 (define_insn "pdist_vis"
7811 [(set (match_operand:DI 0 "register_operand" "=e")
7812 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
7813 (match_operand:V8QI 2 "register_operand" "e")
7814 (match_operand:DI 3 "register_operand" "0")]
7818 [(set_attr "type" "fga")
7819 (set_attr "fptype" "double")])
7821 ;; Edge instructions produce condition codes equivalent to a 'subcc'
7822 ;; with the same operands.
7823 (define_insn "edge8<P:mode>_vis"
7824 [(set (reg:CC_NOOV 100)
7825 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
7826 (match_operand:P 2 "register_operand" "rJ"))
7828 (set (match_operand:SI 0 "register_operand" "=r")
7829 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8))]
7831 "edge8\t%r1, %r2, %0"
7832 [(set_attr "type" "edge")])
7834 (define_insn "edge8l<P:mode>_vis"
7835 [(set (reg:CC_NOOV 100)
7836 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
7837 (match_operand:P 2 "register_operand" "rJ"))
7839 (set (match_operand:SI 0 "register_operand" "=r")
7840 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8L))]
7842 "edge8l\t%r1, %r2, %0"
7843 [(set_attr "type" "edge")])
7845 (define_insn "edge16<P:mode>_vis"
7846 [(set (reg:CC_NOOV 100)
7847 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
7848 (match_operand:P 2 "register_operand" "rJ"))
7850 (set (match_operand:SI 0 "register_operand" "=r")
7851 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16))]
7853 "edge16\t%r1, %r2, %0"
7854 [(set_attr "type" "edge")])
7856 (define_insn "edge16l<P:mode>_vis"
7857 [(set (reg:CC_NOOV 100)
7858 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
7859 (match_operand:P 2 "register_operand" "rJ"))
7861 (set (match_operand:SI 0 "register_operand" "=r")
7862 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16L))]
7864 "edge16l\t%r1, %r2, %0"
7865 [(set_attr "type" "edge")])
7867 (define_insn "edge32<P:mode>_vis"
7868 [(set (reg:CC_NOOV 100)
7869 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
7870 (match_operand:P 2 "register_operand" "rJ"))
7872 (set (match_operand:SI 0 "register_operand" "=r")
7873 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32))]
7875 "edge32\t%r1, %r2, %0"
7876 [(set_attr "type" "edge")])
7878 (define_insn "edge32l<P:mode>_vis"
7879 [(set (reg:CC_NOOV 100)
7880 (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
7881 (match_operand:P 2 "register_operand" "rJ"))
7883 (set (match_operand:SI 0 "register_operand" "=r")
7884 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32L))]
7886 "edge32l\t%r1, %r2, %0"
7887 [(set_attr "type" "edge")])