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 ;; 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)
78 (UNSPECV_PROBE_STACK_RANGE 11)
82 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
83 (define_mode_iterator I [QI HI SI DI])
84 (define_mode_iterator F [SF DF TF])
86 ;; We don't define V1SI because SI should work just fine.
87 (define_mode_iterator V32 [SF V2HI V4QI])
88 (define_mode_iterator V32I [SI V2HI V4QI])
90 (define_mode_iterator V64 [DF V2SI V4HI V8QI])
91 (define_mode_iterator V64I [DI V2SI V4HI V8QI])
93 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
94 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
95 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
96 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
97 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
100 ;; Attribute for cpu type.
101 ;; These must match the values for enum processor_type in sparc.h.
120 (const (symbol_ref "sparc_cpu_attr")))
122 ;; Attribute for the instruction set.
123 ;; At present we only need to distinguish v9/!v9, but for clarity we
124 ;; test TARGET_V8 too.
125 (define_attr "isa" "v7,v8,v9,sparclet"
127 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
128 (symbol_ref "TARGET_V8") (const_string "v8")
129 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
130 (const_string "v7"))))
136 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
144 fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,
147 multi,savew,flushw,iflush,trap"
148 (const_string "ialu"))
150 ;; True if branch/call has empty delay slot and will emit a nop in it
151 (define_attr "empty_delay_slot" "false,true"
152 (symbol_ref "(empty_delay_slot (insn)
153 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
155 (define_attr "branch_type" "none,icc,fcc,reg"
156 (const_string "none"))
158 (define_attr "pic" "false,true"
159 (symbol_ref "(flag_pic != 0 ? PIC_TRUE : PIC_FALSE)"))
161 (define_attr "calls_alloca" "false,true"
162 (symbol_ref "(cfun->calls_alloca != 0
163 ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)"))
165 (define_attr "calls_eh_return" "false,true"
166 (symbol_ref "(crtl->calls_eh_return != 0
167 ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)"))
169 (define_attr "leaf_function" "false,true"
170 (symbol_ref "(current_function_uses_only_leaf_regs != 0
171 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
173 (define_attr "delayed_branch" "false,true"
174 (symbol_ref "(flag_delayed_branch != 0
175 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
177 ;; Length (in # of insns).
178 ;; Beware that setting a length greater or equal to 3 for conditional branches
179 ;; has a side-effect (see output_cbranch and output_v9branch).
180 (define_attr "length" ""
181 (cond [(eq_attr "type" "uncond_branch,call")
182 (if_then_else (eq_attr "empty_delay_slot" "true")
185 (eq_attr "type" "sibcall")
186 (if_then_else (eq_attr "leaf_function" "true")
187 (if_then_else (eq_attr "empty_delay_slot" "true")
190 (if_then_else (eq_attr "empty_delay_slot" "true")
193 (eq_attr "branch_type" "icc")
194 (if_then_else (match_operand 0 "noov_compare64_operator" "")
195 (if_then_else (lt (pc) (match_dup 1))
196 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
197 (if_then_else (eq_attr "empty_delay_slot" "true")
200 (if_then_else (eq_attr "empty_delay_slot" "true")
203 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
204 (if_then_else (eq_attr "empty_delay_slot" "true")
207 (if_then_else (eq_attr "empty_delay_slot" "true")
210 (if_then_else (eq_attr "empty_delay_slot" "true")
213 (eq_attr "branch_type" "fcc")
214 (if_then_else (match_operand 0 "fcc0_register_operand" "")
215 (if_then_else (eq_attr "empty_delay_slot" "true")
216 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
219 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
222 (if_then_else (lt (pc) (match_dup 2))
223 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
224 (if_then_else (eq_attr "empty_delay_slot" "true")
227 (if_then_else (eq_attr "empty_delay_slot" "true")
230 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
231 (if_then_else (eq_attr "empty_delay_slot" "true")
234 (if_then_else (eq_attr "empty_delay_slot" "true")
237 (eq_attr "branch_type" "reg")
238 (if_then_else (lt (pc) (match_dup 2))
239 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
240 (if_then_else (eq_attr "empty_delay_slot" "true")
243 (if_then_else (eq_attr "empty_delay_slot" "true")
246 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
247 (if_then_else (eq_attr "empty_delay_slot" "true")
250 (if_then_else (eq_attr "empty_delay_slot" "true")
256 (define_attr "fptype" "single,double"
257 (const_string "single"))
259 ;; UltraSPARC-III integer load type.
260 (define_attr "us3load_type" "2cycle,3cycle"
261 (const_string "2cycle"))
263 (define_asm_attributes
264 [(set_attr "length" "2")
265 (set_attr "type" "multi")])
267 ;; Attributes for instruction and branch scheduling
268 (define_attr "tls_call_delay" "false,true"
269 (symbol_ref "(tls_call_delay (insn)
270 ? TLS_CALL_DELAY_TRUE : TLS_CALL_DELAY_FALSE)"))
272 (define_attr "in_call_delay" "false,true"
273 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
274 (const_string "false")
275 (eq_attr "type" "load,fpload,store,fpstore")
276 (if_then_else (eq_attr "length" "1")
277 (const_string "true")
278 (const_string "false"))]
279 (if_then_else (and (eq_attr "length" "1")
280 (eq_attr "tls_call_delay" "true"))
281 (const_string "true")
282 (const_string "false"))))
284 (define_attr "eligible_for_sibcall_delay" "false,true"
285 (symbol_ref "(eligible_for_sibcall_delay (insn)
286 ? ELIGIBLE_FOR_SIBCALL_DELAY_TRUE
287 : ELIGIBLE_FOR_SIBCALL_DELAY_FALSE)"))
289 (define_attr "eligible_for_return_delay" "false,true"
290 (symbol_ref "(eligible_for_return_delay (insn)
291 ? ELIGIBLE_FOR_RETURN_DELAY_TRUE
292 : ELIGIBLE_FOR_RETURN_DELAY_FALSE)"))
294 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
295 ;; branches. This would allow us to remove the nop always inserted before
296 ;; a floating point branch.
298 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
299 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
300 ;; This is because doing so will add several pipeline stalls to the path
301 ;; that the load/store did not come from. Unfortunately, there is no way
302 ;; to prevent fill_eager_delay_slots from using load/store without completely
303 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
304 ;; because it prevents us from moving back the final store of inner loops.
306 (define_attr "in_branch_delay" "false,true"
307 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
308 (eq_attr "length" "1"))
309 (const_string "true")
310 (const_string "false")))
312 (define_attr "in_uncond_branch_delay" "false,true"
313 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
314 (eq_attr "length" "1"))
315 (const_string "true")
316 (const_string "false")))
318 (define_attr "in_annul_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_delay (eq_attr "type" "call")
325 [(eq_attr "in_call_delay" "true") (nil) (nil)])
327 (define_delay (eq_attr "type" "sibcall")
328 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
330 (define_delay (eq_attr "type" "branch")
331 [(eq_attr "in_branch_delay" "true")
332 (nil) (eq_attr "in_annul_branch_delay" "true")])
334 (define_delay (eq_attr "type" "uncond_branch")
335 [(eq_attr "in_uncond_branch_delay" "true")
338 (define_delay (eq_attr "type" "return")
339 [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
342 ;; Include SPARC DFA schedulers
344 (include "cypress.md")
345 (include "supersparc.md")
346 (include "hypersparc.md")
348 (include "sparclet.md")
349 (include "ultra1_2.md")
350 (include "ultra3.md")
351 (include "niagara.md")
352 (include "niagara2.md")
355 ;; Operand and operator predicates and constraints
357 (include "predicates.md")
358 (include "constraints.md")
361 ;; Compare instructions.
363 ;; These are just the DEFINE_INSNs to match the patterns and the
364 ;; DEFINE_SPLITs for some of the scc insns that actually require
365 ;; more than one machine instruction. DEFINE_EXPANDs are further down.
367 ;; The compare DEFINE_INSNs.
369 (define_insn "*cmpsi_insn"
371 (compare:CC (match_operand:SI 0 "register_operand" "r")
372 (match_operand:SI 1 "arith_operand" "rI")))]
375 [(set_attr "type" "compare")])
377 (define_insn "*cmpdi_sp64"
379 (compare:CCX (match_operand:DI 0 "register_operand" "r")
380 (match_operand:DI 1 "arith_operand" "rI")))]
383 [(set_attr "type" "compare")])
385 (define_insn "*cmpsf_fpe"
386 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
387 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
388 (match_operand:SF 2 "register_operand" "f")))]
392 return "fcmpes\t%0, %1, %2";
393 return "fcmpes\t%1, %2";
395 [(set_attr "type" "fpcmp")])
397 (define_insn "*cmpdf_fpe"
398 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
399 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
400 (match_operand:DF 2 "register_operand" "e")))]
404 return "fcmped\t%0, %1, %2";
405 return "fcmped\t%1, %2";
407 [(set_attr "type" "fpcmp")
408 (set_attr "fptype" "double")])
410 (define_insn "*cmptf_fpe"
411 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
412 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
413 (match_operand:TF 2 "register_operand" "e")))]
414 "TARGET_FPU && TARGET_HARD_QUAD"
417 return "fcmpeq\t%0, %1, %2";
418 return "fcmpeq\t%1, %2";
420 [(set_attr "type" "fpcmp")])
422 (define_insn "*cmpsf_fp"
423 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
424 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
425 (match_operand:SF 2 "register_operand" "f")))]
429 return "fcmps\t%0, %1, %2";
430 return "fcmps\t%1, %2";
432 [(set_attr "type" "fpcmp")])
434 (define_insn "*cmpdf_fp"
435 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
436 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
437 (match_operand:DF 2 "register_operand" "e")))]
441 return "fcmpd\t%0, %1, %2";
442 return "fcmpd\t%1, %2";
444 [(set_attr "type" "fpcmp")
445 (set_attr "fptype" "double")])
447 (define_insn "*cmptf_fp"
448 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
449 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
450 (match_operand:TF 2 "register_operand" "e")))]
451 "TARGET_FPU && TARGET_HARD_QUAD"
454 return "fcmpq\t%0, %1, %2";
455 return "fcmpq\t%1, %2";
457 [(set_attr "type" "fpcmp")])
459 ;; Next come the scc insns.
461 (define_expand "cstoresi4"
462 [(use (match_operator 1 "comparison_operator"
463 [(match_operand:SI 2 "compare_operand" "")
464 (match_operand:SI 3 "arith_operand" "")]))
465 (clobber (match_operand:SI 0 "register_operand"))]
468 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
469 operands[2] = force_reg (SImode, operands[2]);
470 if (emit_scc_insn (operands)) DONE; else FAIL;
473 (define_expand "cstoredi4"
474 [(use (match_operator 1 "comparison_operator"
475 [(match_operand:DI 2 "compare_operand" "")
476 (match_operand:DI 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 (DImode, operands[2]);
482 if (emit_scc_insn (operands)) DONE; else FAIL;
485 (define_expand "cstore<F:mode>4"
486 [(use (match_operator 1 "comparison_operator"
487 [(match_operand:F 2 "register_operand" "")
488 (match_operand:F 3 "register_operand" "")]))
489 (clobber (match_operand:SI 0 "register_operand"))]
491 { if (emit_scc_insn (operands)) DONE; else FAIL; })
495 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
496 ;; generate addcc/subcc instructions.
498 (define_expand "seqsi_special"
500 (xor:SI (match_operand:SI 1 "register_operand" "")
501 (match_operand:SI 2 "register_operand" "")))
502 (parallel [(set (match_operand:SI 0 "register_operand" "")
503 (eq:SI (match_dup 3) (const_int 0)))
504 (clobber (reg:CC 100))])]
506 { operands[3] = gen_reg_rtx (SImode); })
508 (define_expand "seqdi_special"
510 (xor:DI (match_operand:DI 1 "register_operand" "")
511 (match_operand:DI 2 "register_operand" "")))
512 (set (match_operand:SI 0 "register_operand" "")
513 (eq:SI (match_dup 3) (const_int 0)))]
515 { operands[3] = gen_reg_rtx (DImode); })
517 (define_expand "snesi_special"
519 (xor:SI (match_operand:SI 1 "register_operand" "")
520 (match_operand:SI 2 "register_operand" "")))
521 (parallel [(set (match_operand:SI 0 "register_operand" "")
522 (ne:SI (match_dup 3) (const_int 0)))
523 (clobber (reg:CC 100))])]
525 { operands[3] = gen_reg_rtx (SImode); })
527 (define_expand "snedi_special"
529 (xor:DI (match_operand:DI 1 "register_operand" "")
530 (match_operand:DI 2 "register_operand" "")))
531 (set (match_operand:SI 0 "register_operand" "")
532 (ne:SI (match_dup 3) (const_int 0)))]
534 { operands[3] = gen_reg_rtx (DImode); })
537 ;; Now the DEFINE_INSNs for the scc cases.
539 ;; The SEQ and SNE patterns are special because they can be done
540 ;; without any branching and do not involve a COMPARE. We want
541 ;; them to always use the splits below so the results can be
544 (define_insn_and_split "*snesi_zero"
545 [(set (match_operand:SI 0 "register_operand" "=r")
546 (ne:SI (match_operand:SI 1 "register_operand" "r")
548 (clobber (reg:CC 100))]
552 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
554 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
556 [(set_attr "length" "2")])
558 (define_insn_and_split "*neg_snesi_zero"
559 [(set (match_operand:SI 0 "register_operand" "=r")
560 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
562 (clobber (reg:CC 100))]
566 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
568 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
570 [(set_attr "length" "2")])
572 (define_insn_and_split "*snesi_zero_extend"
573 [(set (match_operand:DI 0 "register_operand" "=r")
574 (ne:DI (match_operand:SI 1 "register_operand" "r")
576 (clobber (reg:CC 100))]
580 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
583 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
585 (ltu:SI (reg:CC_NOOV 100)
588 [(set_attr "length" "2")])
590 (define_insn_and_split "*snedi_zero"
591 [(set (match_operand:DI 0 "register_operand" "=&r")
592 (ne:DI (match_operand:DI 1 "register_operand" "r")
596 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
597 [(set (match_dup 0) (const_int 0))
598 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
603 [(set_attr "length" "2")])
605 (define_insn_and_split "*neg_snedi_zero"
606 [(set (match_operand:DI 0 "register_operand" "=&r")
607 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
611 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
612 [(set (match_dup 0) (const_int 0))
613 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
618 [(set_attr "length" "2")])
620 (define_insn_and_split "*snedi_zero_trunc"
621 [(set (match_operand:SI 0 "register_operand" "=&r")
622 (ne:SI (match_operand:DI 1 "register_operand" "r")
626 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
627 [(set (match_dup 0) (const_int 0))
628 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
633 [(set_attr "length" "2")])
635 (define_insn_and_split "*seqsi_zero"
636 [(set (match_operand:SI 0 "register_operand" "=r")
637 (eq:SI (match_operand:SI 1 "register_operand" "r")
639 (clobber (reg:CC 100))]
643 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
645 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
647 [(set_attr "length" "2")])
649 (define_insn_and_split "*neg_seqsi_zero"
650 [(set (match_operand:SI 0 "register_operand" "=r")
651 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
653 (clobber (reg:CC 100))]
657 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
659 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
661 [(set_attr "length" "2")])
663 (define_insn_and_split "*seqsi_zero_extend"
664 [(set (match_operand:DI 0 "register_operand" "=r")
665 (eq:DI (match_operand:SI 1 "register_operand" "r")
667 (clobber (reg:CC 100))]
671 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
674 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
676 (ltu:SI (reg:CC_NOOV 100)
679 [(set_attr "length" "2")])
681 (define_insn_and_split "*seqdi_zero"
682 [(set (match_operand:DI 0 "register_operand" "=&r")
683 (eq:DI (match_operand:DI 1 "register_operand" "r")
687 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
688 [(set (match_dup 0) (const_int 0))
689 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
694 [(set_attr "length" "2")])
696 (define_insn_and_split "*neg_seqdi_zero"
697 [(set (match_operand:DI 0 "register_operand" "=&r")
698 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
702 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
703 [(set (match_dup 0) (const_int 0))
704 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
709 [(set_attr "length" "2")])
711 (define_insn_and_split "*seqdi_zero_trunc"
712 [(set (match_operand:SI 0 "register_operand" "=&r")
713 (eq:SI (match_operand:DI 1 "register_operand" "r")
717 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
718 [(set (match_dup 0) (const_int 0))
719 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
724 [(set_attr "length" "2")])
726 ;; We can also do (x + (i == 0)) and related, so put them in.
727 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
730 (define_insn_and_split "*x_plus_i_ne_0"
731 [(set (match_operand:SI 0 "register_operand" "=r")
732 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
734 (match_operand:SI 2 "register_operand" "r")))
735 (clobber (reg:CC 100))]
739 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
741 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
744 [(set_attr "length" "2")])
746 (define_insn_and_split "*x_minus_i_ne_0"
747 [(set (match_operand:SI 0 "register_operand" "=r")
748 (minus:SI (match_operand:SI 2 "register_operand" "r")
749 (ne:SI (match_operand:SI 1 "register_operand" "r")
751 (clobber (reg:CC 100))]
755 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
757 (set (match_dup 0) (minus:SI (match_dup 2)
758 (ltu:SI (reg:CC 100) (const_int 0))))]
760 [(set_attr "length" "2")])
762 (define_insn_and_split "*x_plus_i_eq_0"
763 [(set (match_operand:SI 0 "register_operand" "=r")
764 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
766 (match_operand:SI 2 "register_operand" "r")))
767 (clobber (reg:CC 100))]
771 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
773 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
776 [(set_attr "length" "2")])
778 (define_insn_and_split "*x_minus_i_eq_0"
779 [(set (match_operand:SI 0 "register_operand" "=r")
780 (minus:SI (match_operand:SI 2 "register_operand" "r")
781 (eq:SI (match_operand:SI 1 "register_operand" "r")
783 (clobber (reg:CC 100))]
787 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
789 (set (match_dup 0) (minus:SI (match_dup 2)
790 (geu:SI (reg:CC 100) (const_int 0))))]
792 [(set_attr "length" "2")])
794 ;; We can also do GEU and LTU directly, but these operate after a compare.
795 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
798 (define_insn "*sltu_insn"
799 [(set (match_operand:SI 0 "register_operand" "=r")
800 (ltu:SI (reg:CC 100) (const_int 0)))]
803 [(set_attr "type" "ialuX")])
805 (define_insn "*neg_sltu_insn"
806 [(set (match_operand:SI 0 "register_operand" "=r")
807 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
810 [(set_attr "type" "ialuX")])
812 ;; ??? Combine should canonicalize these next two to the same pattern.
813 (define_insn "*neg_sltu_minus_x"
814 [(set (match_operand:SI 0 "register_operand" "=r")
815 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
816 (match_operand:SI 1 "arith_operand" "rI")))]
819 [(set_attr "type" "ialuX")])
821 (define_insn "*neg_sltu_plus_x"
822 [(set (match_operand:SI 0 "register_operand" "=r")
823 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
824 (match_operand:SI 1 "arith_operand" "rI"))))]
827 [(set_attr "type" "ialuX")])
829 (define_insn "*sgeu_insn"
830 [(set (match_operand:SI 0 "register_operand" "=r")
831 (geu:SI (reg:CC 100) (const_int 0)))]
834 [(set_attr "type" "ialuX")])
836 (define_insn "*neg_sgeu_insn"
837 [(set (match_operand:SI 0 "register_operand" "=r")
838 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
841 [(set_attr "type" "ialuX")])
843 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
844 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
847 (define_insn "*sltu_plus_x"
848 [(set (match_operand:SI 0 "register_operand" "=r")
849 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
850 (match_operand:SI 1 "arith_operand" "rI")))]
853 [(set_attr "type" "ialuX")])
855 (define_insn "*sltu_plus_x_plus_y"
856 [(set (match_operand:SI 0 "register_operand" "=r")
857 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
858 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
859 (match_operand:SI 2 "arith_operand" "rI"))))]
862 [(set_attr "type" "ialuX")])
864 (define_insn "*x_minus_sltu"
865 [(set (match_operand:SI 0 "register_operand" "=r")
866 (minus:SI (match_operand:SI 1 "register_operand" "r")
867 (ltu:SI (reg:CC 100) (const_int 0))))]
870 [(set_attr "type" "ialuX")])
872 ;; ??? Combine should canonicalize these next two to the same pattern.
873 (define_insn "*x_minus_y_minus_sltu"
874 [(set (match_operand:SI 0 "register_operand" "=r")
875 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
876 (match_operand:SI 2 "arith_operand" "rI"))
877 (ltu:SI (reg:CC 100) (const_int 0))))]
880 [(set_attr "type" "ialuX")])
882 (define_insn "*x_minus_sltu_plus_y"
883 [(set (match_operand:SI 0 "register_operand" "=r")
884 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
885 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
886 (match_operand:SI 2 "arith_operand" "rI"))))]
889 [(set_attr "type" "ialuX")])
891 (define_insn "*sgeu_plus_x"
892 [(set (match_operand:SI 0 "register_operand" "=r")
893 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
894 (match_operand:SI 1 "register_operand" "r")))]
897 [(set_attr "type" "ialuX")])
899 (define_insn "*x_minus_sgeu"
900 [(set (match_operand:SI 0 "register_operand" "=r")
901 (minus:SI (match_operand:SI 1 "register_operand" "r")
902 (geu:SI (reg:CC 100) (const_int 0))))]
905 [(set_attr "type" "ialuX")])
908 [(set (match_operand:SI 0 "register_operand" "")
909 (match_operator:SI 2 "noov_compare_operator"
910 [(match_operand 1 "icc_or_fcc_register_operand" "")
913 && REGNO (operands[1]) == SPARC_ICC_REG
914 && (GET_MODE (operands[1]) == CCXmode
915 /* 32-bit LTU/GEU are better implemented using addx/subx. */
916 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
917 [(set (match_dup 0) (const_int 0))
919 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
925 ;; These control RTL generation for conditional jump insns
927 (define_expand "cbranchcc4"
929 (if_then_else (match_operator 0 "comparison_operator"
930 [(match_operand 1 "compare_operand" "")
931 (match_operand 2 "const_zero_operand" "")])
932 (label_ref (match_operand 3 "" ""))
937 (define_expand "cbranchsi4"
938 [(use (match_operator 0 "comparison_operator"
939 [(match_operand:SI 1 "compare_operand" "")
940 (match_operand:SI 2 "arith_operand" "")]))
941 (use (match_operand 3 ""))]
944 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
945 operands[1] = force_reg (SImode, operands[1]);
946 emit_conditional_branch_insn (operands);
950 (define_expand "cbranchdi4"
951 [(use (match_operator 0 "comparison_operator"
952 [(match_operand:DI 1 "compare_operand" "")
953 (match_operand:DI 2 "arith_operand" "")]))
954 (use (match_operand 3 ""))]
957 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
958 operands[1] = force_reg (DImode, operands[1]);
959 emit_conditional_branch_insn (operands);
963 (define_expand "cbranch<F:mode>4"
964 [(use (match_operator 0 "comparison_operator"
965 [(match_operand:F 1 "register_operand" "")
966 (match_operand:F 2 "register_operand" "")]))
967 (use (match_operand 3 ""))]
969 { emit_conditional_branch_insn (operands); DONE; })
972 ;; Now match both normal and inverted jump.
974 ;; XXX fpcmp nop braindamage
975 (define_insn "*normal_branch"
977 (if_then_else (match_operator 0 "noov_compare_operator"
978 [(reg 100) (const_int 0)])
979 (label_ref (match_operand 1 "" ""))
983 return output_cbranch (operands[0], operands[1], 1, 0,
984 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
987 [(set_attr "type" "branch")
988 (set_attr "branch_type" "icc")])
990 ;; XXX fpcmp nop braindamage
991 (define_insn "*inverted_branch"
993 (if_then_else (match_operator 0 "noov_compare_operator"
994 [(reg 100) (const_int 0)])
996 (label_ref (match_operand 1 "" ""))))]
999 return output_cbranch (operands[0], operands[1], 1, 1,
1000 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1003 [(set_attr "type" "branch")
1004 (set_attr "branch_type" "icc")])
1006 ;; XXX fpcmp nop braindamage
1007 (define_insn "*normal_fp_branch"
1009 (if_then_else (match_operator 1 "comparison_operator"
1010 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1012 (label_ref (match_operand 2 "" ""))
1016 return output_cbranch (operands[1], operands[2], 2, 0,
1017 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1020 [(set_attr "type" "branch")
1021 (set_attr "branch_type" "fcc")])
1023 ;; XXX fpcmp nop braindamage
1024 (define_insn "*inverted_fp_branch"
1026 (if_then_else (match_operator 1 "comparison_operator"
1027 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1030 (label_ref (match_operand 2 "" ""))))]
1033 return output_cbranch (operands[1], operands[2], 2, 1,
1034 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1037 [(set_attr "type" "branch")
1038 (set_attr "branch_type" "fcc")])
1040 ;; XXX fpcmp nop braindamage
1041 (define_insn "*normal_fpe_branch"
1043 (if_then_else (match_operator 1 "comparison_operator"
1044 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1046 (label_ref (match_operand 2 "" ""))
1050 return output_cbranch (operands[1], operands[2], 2, 0,
1051 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1054 [(set_attr "type" "branch")
1055 (set_attr "branch_type" "fcc")])
1057 ;; XXX fpcmp nop braindamage
1058 (define_insn "*inverted_fpe_branch"
1060 (if_then_else (match_operator 1 "comparison_operator"
1061 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1064 (label_ref (match_operand 2 "" ""))))]
1067 return output_cbranch (operands[1], operands[2], 2, 1,
1068 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1071 [(set_attr "type" "branch")
1072 (set_attr "branch_type" "fcc")])
1074 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1075 ;; in the architecture.
1077 ;; There are no 32 bit brreg insns.
1080 (define_insn "*normal_int_branch_sp64"
1082 (if_then_else (match_operator 0 "v9_register_compare_operator"
1083 [(match_operand:DI 1 "register_operand" "r")
1085 (label_ref (match_operand 2 "" ""))
1089 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1090 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1093 [(set_attr "type" "branch")
1094 (set_attr "branch_type" "reg")])
1097 (define_insn "*inverted_int_branch_sp64"
1099 (if_then_else (match_operator 0 "v9_register_compare_operator"
1100 [(match_operand:DI 1 "register_operand" "r")
1103 (label_ref (match_operand 2 "" ""))))]
1106 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1107 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1110 [(set_attr "type" "branch")
1111 (set_attr "branch_type" "reg")])
1114 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1115 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1116 ;; that adds the PC value at the call point to register #(operand 3).
1118 (define_insn "load_pcrel_sym<P:mode>"
1119 [(set (match_operand:P 0 "register_operand" "=r")
1120 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1121 (match_operand:P 2 "call_address_operand" "")
1122 (match_operand:P 3 "const_int_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1123 (clobber (reg:P 15))]
1124 "REGNO (operands[0]) == INTVAL (operands[3])"
1126 if (flag_delayed_branch)
1127 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1129 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1131 [(set (attr "type") (const_string "multi"))
1132 (set (attr "length")
1133 (if_then_else (eq_attr "delayed_branch" "true")
1138 ;; Integer move instructions
1140 (define_expand "movqi"
1141 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1142 (match_operand:QI 1 "general_operand" ""))]
1145 if (sparc_expand_move (QImode, operands))
1149 (define_insn "*movqi_insn"
1150 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1151 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1152 "(register_operand (operands[0], QImode)
1153 || register_or_zero_operand (operands[1], QImode))"
1158 [(set_attr "type" "*,load,store")
1159 (set_attr "us3load_type" "*,3cycle,*")])
1161 (define_expand "movhi"
1162 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1163 (match_operand:HI 1 "general_operand" ""))]
1166 if (sparc_expand_move (HImode, operands))
1170 (define_insn "*movhi_insn"
1171 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1172 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1173 "(register_operand (operands[0], HImode)
1174 || register_or_zero_operand (operands[1], HImode))"
1177 sethi\t%%hi(%a1), %0
1180 [(set_attr "type" "*,*,load,store")
1181 (set_attr "us3load_type" "*,*,3cycle,*")])
1183 ;; We always work with constants here.
1184 (define_insn "*movhi_lo_sum"
1185 [(set (match_operand:HI 0 "register_operand" "=r")
1186 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1187 (match_operand:HI 2 "small_int_operand" "I")))]
1191 (define_expand "movsi"
1192 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1193 (match_operand:SI 1 "general_operand" ""))]
1196 if (sparc_expand_move (SImode, operands))
1200 (define_insn "*movsi_insn"
1201 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d")
1202 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,f,m,f,J"))]
1203 "(register_operand (operands[0], SImode)
1204 || register_or_zero_operand (operands[1], SImode))"
1207 sethi\t%%hi(%a1), %0
1214 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")])
1216 (define_insn "*movsi_lo_sum"
1217 [(set (match_operand:SI 0 "register_operand" "=r")
1218 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1219 (match_operand:SI 2 "immediate_operand" "in")))]
1221 "or\t%1, %%lo(%a2), %0")
1223 (define_insn "*movsi_high"
1224 [(set (match_operand:SI 0 "register_operand" "=r")
1225 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1227 "sethi\t%%hi(%a1), %0")
1229 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1230 ;; so that CSE won't optimize the address computation away.
1231 (define_insn "movsi_lo_sum_pic"
1232 [(set (match_operand:SI 0 "register_operand" "=r")
1233 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1234 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1237 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1238 return "xor\t%1, %%gdop_lox10(%a2), %0";
1240 return "or\t%1, %%lo(%a2), %0";
1244 (define_insn "movsi_high_pic"
1245 [(set (match_operand:SI 0 "register_operand" "=r")
1246 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1247 "flag_pic && check_pic (1)"
1249 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1250 return "sethi\t%%gdop_hix22(%a1), %0";
1252 return "sethi\t%%hi(%a1), %0";
1256 (define_insn "movsi_pic_gotdata_op"
1257 [(set (match_operand:SI 0 "register_operand" "=r")
1258 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1259 (match_operand:SI 2 "register_operand" "r")
1260 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1261 "flag_pic && check_pic (1)"
1263 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1264 return "ld\t[%1 + %2], %0, %%gdop(%a3)";
1266 return "ld\t[%1 + %2], %0";
1269 [(set_attr "type" "load")])
1271 (define_expand "movsi_pic_label_ref"
1272 [(set (match_dup 3) (high:SI
1273 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1274 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1275 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1276 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1277 (set (match_operand:SI 0 "register_operand" "=r")
1278 (minus:SI (match_dup 5) (match_dup 4)))]
1281 crtl->uses_pic_offset_table = 1;
1282 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1283 if (!can_create_pseudo_p ())
1285 operands[3] = operands[0];
1286 operands[4] = operands[0];
1290 operands[3] = gen_reg_rtx (SImode);
1291 operands[4] = gen_reg_rtx (SImode);
1293 operands[5] = pic_offset_table_rtx;
1296 (define_insn "*movsi_high_pic_label_ref"
1297 [(set (match_operand:SI 0 "register_operand" "=r")
1299 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1300 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1302 "sethi\t%%hi(%a2-(%a1-.)), %0")
1304 (define_insn "*movsi_lo_sum_pic_label_ref"
1305 [(set (match_operand:SI 0 "register_operand" "=r")
1306 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1307 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1308 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1310 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1312 ;; Set up the PIC register for VxWorks.
1314 (define_expand "vxworks_load_got"
1316 (high:SI (match_dup 1)))
1318 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1320 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1321 "TARGET_VXWORKS_RTP"
1323 operands[0] = pic_offset_table_rtx;
1324 operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1325 operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1328 (define_expand "movdi"
1329 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1330 (match_operand:DI 1 "general_operand" ""))]
1333 if (sparc_expand_move (DImode, operands))
1337 ;; Be careful, fmovd does not exist when !v9.
1338 ;; We match MEM moves directly when we have correct even
1339 ;; numbered registers, but fall into splits otherwise.
1340 ;; The constraint ordering here is really important to
1341 ;; avoid insane problems in reload, especially for patterns
1344 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1345 ;; (const_int -5016)))
1349 (define_insn "*movdi_insn_sp32"
1350 [(set (match_operand:DI 0 "nonimmediate_operand"
1351 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1352 (match_operand:DI 1 "input_operand"
1353 " J,U,T,r,o,i,r, f, T, o, f, f"))]
1355 && (register_operand (operands[0], DImode)
1356 || register_or_zero_operand (operands[1], DImode))"
1370 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1371 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1373 (define_insn "*movdi_insn_sp32_v9"
1374 [(set (match_operand:DI 0 "nonimmediate_operand"
1375 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1376 (match_operand:DI 1 "input_operand"
1377 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1380 && (register_operand (operands[0], DImode)
1381 || register_or_zero_operand (operands[1], DImode))"
1398 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
1399 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
1400 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
1402 (define_insn "*movdi_insn_sp64"
1403 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b")
1404 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,e,W,e,J"))]
1406 && (register_operand (operands[0], DImode)
1407 || register_or_zero_operand (operands[1], DImode))"
1410 sethi\t%%hi(%a1), %0
1417 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")
1418 (set_attr "fptype" "*,*,*,*,double,*,*,double")])
1420 (define_expand "movdi_pic_label_ref"
1421 [(set (match_dup 3) (high:DI
1422 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1423 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1424 (set (match_dup 4) (lo_sum:DI (match_dup 3)
1425 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1426 (set (match_operand:DI 0 "register_operand" "=r")
1427 (minus:DI (match_dup 5) (match_dup 4)))]
1428 "TARGET_ARCH64 && flag_pic"
1430 crtl->uses_pic_offset_table = 1;
1431 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1432 if (!can_create_pseudo_p ())
1434 operands[3] = operands[0];
1435 operands[4] = operands[0];
1439 operands[3] = gen_reg_rtx (DImode);
1440 operands[4] = gen_reg_rtx (DImode);
1442 operands[5] = pic_offset_table_rtx;
1445 (define_insn "*movdi_high_pic_label_ref"
1446 [(set (match_operand:DI 0 "register_operand" "=r")
1448 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1449 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1450 "TARGET_ARCH64 && flag_pic"
1451 "sethi\t%%hi(%a2-(%a1-.)), %0")
1453 (define_insn "*movdi_lo_sum_pic_label_ref"
1454 [(set (match_operand:DI 0 "register_operand" "=r")
1455 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1456 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
1457 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1458 "TARGET_ARCH64 && flag_pic"
1459 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1461 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
1462 ;; in sparc.c to see what is going on here... PIC stuff comes first.
1464 (define_insn "movdi_lo_sum_pic"
1465 [(set (match_operand:DI 0 "register_operand" "=r")
1466 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1467 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1468 "TARGET_ARCH64 && flag_pic"
1470 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1471 return "xor\t%1, %%gdop_lox10(%a2), %0";
1473 return "or\t%1, %%lo(%a2), %0";
1477 (define_insn "movdi_high_pic"
1478 [(set (match_operand:DI 0 "register_operand" "=r")
1479 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1480 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1482 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1483 return "sethi\t%%gdop_hix22(%a1), %0";
1485 return "sethi\t%%hi(%a1), %0";
1489 (define_insn "movdi_pic_gotdata_op"
1490 [(set (match_operand:DI 0 "register_operand" "=r")
1491 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1492 (match_operand:DI 2 "register_operand" "r")
1493 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1494 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1496 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1497 return "ldx\t[%1 + %2], %0, %%gdop(%a3)";
1499 return "ldx\t[%1 + %2], %0";
1502 [(set_attr "type" "load")])
1504 (define_insn "*sethi_di_medlow_embmedany_pic"
1505 [(set (match_operand:DI 0 "register_operand" "=r")
1506 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
1507 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
1508 "sethi\t%%hi(%a1), %0")
1510 (define_insn "*sethi_di_medlow"
1511 [(set (match_operand:DI 0 "register_operand" "=r")
1512 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
1513 "TARGET_CM_MEDLOW && check_pic (1)"
1514 "sethi\t%%hi(%a1), %0")
1516 (define_insn "*losum_di_medlow"
1517 [(set (match_operand:DI 0 "register_operand" "=r")
1518 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1519 (match_operand:DI 2 "symbolic_operand" "")))]
1521 "or\t%1, %%lo(%a2), %0")
1523 (define_insn "seth44"
1524 [(set (match_operand:DI 0 "register_operand" "=r")
1525 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
1527 "sethi\t%%h44(%a1), %0")
1529 (define_insn "setm44"
1530 [(set (match_operand:DI 0 "register_operand" "=r")
1531 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1532 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
1534 "or\t%1, %%m44(%a2), %0")
1536 (define_insn "setl44"
1537 [(set (match_operand:DI 0 "register_operand" "=r")
1538 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1539 (match_operand:DI 2 "symbolic_operand" "")))]
1541 "or\t%1, %%l44(%a2), %0")
1543 (define_insn "sethh"
1544 [(set (match_operand:DI 0 "register_operand" "=r")
1545 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
1547 "sethi\t%%hh(%a1), %0")
1549 (define_insn "setlm"
1550 [(set (match_operand:DI 0 "register_operand" "=r")
1551 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
1553 "sethi\t%%lm(%a1), %0")
1555 (define_insn "sethm"
1556 [(set (match_operand:DI 0 "register_operand" "=r")
1557 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1558 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
1560 "or\t%1, %%hm(%a2), %0")
1562 (define_insn "setlo"
1563 [(set (match_operand:DI 0 "register_operand" "=r")
1564 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1565 (match_operand:DI 2 "symbolic_operand" "")))]
1567 "or\t%1, %%lo(%a2), %0")
1569 (define_insn "embmedany_sethi"
1570 [(set (match_operand:DI 0 "register_operand" "=r")
1571 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
1572 "TARGET_CM_EMBMEDANY && check_pic (1)"
1573 "sethi\t%%hi(%a1), %0")
1575 (define_insn "embmedany_losum"
1576 [(set (match_operand:DI 0 "register_operand" "=r")
1577 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1578 (match_operand:DI 2 "data_segment_operand" "")))]
1579 "TARGET_CM_EMBMEDANY"
1580 "add\t%1, %%lo(%a2), %0")
1582 (define_insn "embmedany_brsum"
1583 [(set (match_operand:DI 0 "register_operand" "=r")
1584 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
1585 "TARGET_CM_EMBMEDANY"
1588 (define_insn "embmedany_textuhi"
1589 [(set (match_operand:DI 0 "register_operand" "=r")
1590 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
1591 "TARGET_CM_EMBMEDANY && check_pic (1)"
1592 "sethi\t%%uhi(%a1), %0")
1594 (define_insn "embmedany_texthi"
1595 [(set (match_operand:DI 0 "register_operand" "=r")
1596 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
1597 "TARGET_CM_EMBMEDANY && check_pic (1)"
1598 "sethi\t%%hi(%a1), %0")
1600 (define_insn "embmedany_textulo"
1601 [(set (match_operand:DI 0 "register_operand" "=r")
1602 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1603 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
1604 "TARGET_CM_EMBMEDANY"
1605 "or\t%1, %%ulo(%a2), %0")
1607 (define_insn "embmedany_textlo"
1608 [(set (match_operand:DI 0 "register_operand" "=r")
1609 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1610 (match_operand:DI 2 "text_segment_operand" "")))]
1611 "TARGET_CM_EMBMEDANY"
1612 "or\t%1, %%lo(%a2), %0")
1614 ;; Now some patterns to help reload out a bit.
1615 (define_expand "reload_indi"
1616 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1617 (match_operand:DI 1 "immediate_operand" "")
1618 (match_operand:TI 2 "register_operand" "=&r")])]
1620 || TARGET_CM_EMBMEDANY)
1623 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1627 (define_expand "reload_outdi"
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 ;; Split up putting CONSTs and REGs into DI regs when !arch64
1641 [(set (match_operand:DI 0 "register_operand" "")
1642 (match_operand:DI 1 "const_int_operand" ""))]
1643 "! TARGET_ARCH64 && reload_completed"
1644 [(clobber (const_int 0))]
1646 #if HOST_BITS_PER_WIDE_INT == 32
1647 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1648 (INTVAL (operands[1]) < 0) ?
1651 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1654 unsigned int low, high;
1656 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
1657 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
1658 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
1660 /* Slick... but this trick loses if this subreg constant part
1661 can be done in one insn. */
1663 && ! SPARC_SETHI32_P (high)
1664 && ! SPARC_SIMM13_P (high))
1665 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1666 gen_highpart (SImode, operands[0])));
1668 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
1674 [(set (match_operand:DI 0 "register_operand" "")
1675 (match_operand:DI 1 "const_double_operand" ""))]
1679 && ((GET_CODE (operands[0]) == REG
1680 && REGNO (operands[0]) < 32)
1681 || (GET_CODE (operands[0]) == SUBREG
1682 && GET_CODE (SUBREG_REG (operands[0])) == REG
1683 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1684 [(clobber (const_int 0))]
1686 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1687 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
1689 /* Slick... but this trick loses if this subreg constant part
1690 can be done in one insn. */
1691 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
1692 && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
1693 && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
1695 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1696 gen_highpart (SImode, operands[0])));
1700 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1701 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
1707 [(set (match_operand:DI 0 "register_operand" "")
1708 (match_operand:DI 1 "register_operand" ""))]
1712 && ((GET_CODE (operands[0]) == REG
1713 && REGNO (operands[0]) < 32)
1714 || (GET_CODE (operands[0]) == SUBREG
1715 && GET_CODE (SUBREG_REG (operands[0])) == REG
1716 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1717 [(clobber (const_int 0))]
1719 rtx set_dest = operands[0];
1720 rtx set_src = operands[1];
1724 dest1 = gen_highpart (SImode, set_dest);
1725 dest2 = gen_lowpart (SImode, set_dest);
1726 src1 = gen_highpart (SImode, set_src);
1727 src2 = gen_lowpart (SImode, set_src);
1729 /* Now emit using the real source and destination we found, swapping
1730 the order if we detect overlap. */
1731 if (reg_overlap_mentioned_p (dest1, src2))
1733 emit_insn (gen_movsi (dest2, src2));
1734 emit_insn (gen_movsi (dest1, src1));
1738 emit_insn (gen_movsi (dest1, src1));
1739 emit_insn (gen_movsi (dest2, src2));
1744 ;; Now handle the cases of memory moves from/to non-even
1745 ;; DI mode register pairs.
1747 [(set (match_operand:DI 0 "register_operand" "")
1748 (match_operand:DI 1 "memory_operand" ""))]
1751 && sparc_splitdi_legitimate (operands[0], operands[1]))"
1752 [(clobber (const_int 0))]
1754 rtx word0 = adjust_address (operands[1], SImode, 0);
1755 rtx word1 = adjust_address (operands[1], SImode, 4);
1756 rtx high_part = gen_highpart (SImode, operands[0]);
1757 rtx low_part = gen_lowpart (SImode, operands[0]);
1759 if (reg_overlap_mentioned_p (high_part, word1))
1761 emit_insn (gen_movsi (low_part, word1));
1762 emit_insn (gen_movsi (high_part, word0));
1766 emit_insn (gen_movsi (high_part, word0));
1767 emit_insn (gen_movsi (low_part, word1));
1773 [(set (match_operand:DI 0 "memory_operand" "")
1774 (match_operand:DI 1 "register_operand" ""))]
1777 && sparc_splitdi_legitimate (operands[1], operands[0]))"
1778 [(clobber (const_int 0))]
1780 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
1781 gen_highpart (SImode, operands[1])));
1782 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
1783 gen_lowpart (SImode, operands[1])));
1788 [(set (match_operand:DI 0 "memory_operand" "")
1789 (match_operand:DI 1 "const_zero_operand" ""))]
1793 && ! mem_min_alignment (operands[0], 8)))
1794 && offsettable_memref_p (operands[0])"
1795 [(clobber (const_int 0))]
1797 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
1798 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
1803 ;; Floating point and vector move instructions
1805 ;; Yes, you guessed it right, the former movsf expander.
1806 (define_expand "mov<V32:mode>"
1807 [(set (match_operand:V32 0 "nonimmediate_operand" "")
1808 (match_operand:V32 1 "general_operand" ""))]
1809 "<V32:MODE>mode == SFmode || TARGET_VIS"
1811 if (sparc_expand_move (<V32:MODE>mode, operands))
1815 (define_insn "*movsf_insn"
1816 [(set (match_operand:V32 0 "nonimmediate_operand" "=d,f,*r,*r,*r,f,*r,m,m")
1817 (match_operand:V32 1 "input_operand" "GY,f,*rRY,Q,S,m,m,f,*rGY"))]
1819 && (register_operand (operands[0], <V32:MODE>mode)
1820 || register_or_zero_operand (operands[1], <V32:MODE>mode))"
1822 if (GET_CODE (operands[1]) == CONST_DOUBLE
1823 && (which_alternative == 2
1824 || which_alternative == 3
1825 || which_alternative == 4))
1830 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1831 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1832 operands[1] = GEN_INT (i);
1835 switch (which_alternative)
1838 return "fzeros\t%0";
1840 return "fmovs\t%1, %0";
1842 return "mov\t%1, %0";
1844 return "sethi\t%%hi(%a1), %0";
1849 return "ld\t%1, %0";
1852 return "st\t%r1, %0";
1857 [(set_attr "type" "fga,fpmove,*,*,*,fpload,load,fpstore,store")])
1859 ;; Exactly the same as above, except that all `f' cases are deleted.
1860 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1863 (define_insn "*movsf_insn_no_fpu"
1864 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
1865 (match_operand:SF 1 "input_operand" "rR,Q,S,m,rG"))]
1867 && (register_operand (operands[0], SFmode)
1868 || register_or_zero_operand (operands[1], SFmode))"
1870 if (GET_CODE (operands[1]) == CONST_DOUBLE
1871 && (which_alternative == 0
1872 || which_alternative == 1
1873 || which_alternative == 2))
1878 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1879 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1880 operands[1] = GEN_INT (i);
1883 switch (which_alternative)
1886 return "mov\t%1, %0";
1888 return "sethi\t%%hi(%a1), %0";
1892 return "ld\t%1, %0";
1894 return "st\t%r1, %0";
1899 [(set_attr "type" "*,*,*,load,store")])
1901 ;; The following 3 patterns build SFmode constants in integer registers.
1903 (define_insn "*movsf_lo_sum"
1904 [(set (match_operand:SF 0 "register_operand" "=r")
1905 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
1906 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
1912 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
1913 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1914 operands[2] = GEN_INT (i);
1915 return "or\t%1, %%lo(%a2), %0";
1918 (define_insn "*movsf_high"
1919 [(set (match_operand:SF 0 "register_operand" "=r")
1920 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
1926 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1927 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1928 operands[1] = GEN_INT (i);
1929 return "sethi\t%%hi(%1), %0";
1933 [(set (match_operand:SF 0 "register_operand" "")
1934 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
1935 "REG_P (operands[0]) && REGNO (operands[0]) < 32"
1936 [(set (match_dup 0) (high:SF (match_dup 1)))
1937 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
1939 ;; Yes, you again guessed it right, the former movdf expander.
1940 (define_expand "mov<V64:mode>"
1941 [(set (match_operand:V64 0 "nonimmediate_operand" "")
1942 (match_operand:V64 1 "general_operand" ""))]
1943 "<V64:MODE>mode == DFmode || TARGET_VIS"
1945 if (sparc_expand_move (<V64:MODE>mode, operands))
1949 ;; Be careful, fmovd does not exist when !v9.
1950 (define_insn "*movdf_insn_sp32"
1951 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
1952 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
1955 && (register_operand (operands[0], DFmode)
1956 || register_or_zero_operand (operands[1], DFmode))"
1968 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
1969 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
1971 (define_insn "*movdf_insn_sp32_no_fpu"
1972 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
1973 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
1976 && (register_operand (operands[0], DFmode)
1977 || register_or_zero_operand (operands[1], DFmode))"
1984 [(set_attr "type" "load,store,*,*,*")
1985 (set_attr "length" "*,*,2,2,2")])
1987 ;; We have available v9 double floats but not 64-bit integer registers.
1988 (define_insn "*movdf_insn_sp32_v9"
1989 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o")
1990 (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYDF,*rGYf"))]
1994 && (register_operand (operands[0], <V64:MODE>mode)
1995 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2007 [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
2008 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2009 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2011 (define_insn "*movdf_insn_sp32_v9_no_fpu"
2012 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2013 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2017 && (register_operand (operands[0], DFmode)
2018 || register_or_zero_operand (operands[1], DFmode))"
2025 [(set_attr "type" "load,store,store,*,*")
2026 (set_attr "length" "*,*,*,2,2")])
2028 ;; We have available both v9 double floats and 64-bit integer registers.
2029 (define_insn "*movdf_insn_sp64"
2030 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r")
2031 (match_operand:V64 1 "input_operand" "GY,e,W#F,e,*rGY,m,*rGY,DF"))]
2034 && (register_operand (operands[0], <V64:MODE>mode)
2035 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2045 [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
2046 (set_attr "length" "*,*,*,*,*,*,*,2")
2047 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
2049 (define_insn "*movdf_insn_sp64_no_fpu"
2050 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2051 (match_operand:DF 1 "input_operand" "r,m,rG"))]
2054 && (register_operand (operands[0], DFmode)
2055 || register_or_zero_operand (operands[1], DFmode))"
2060 [(set_attr "type" "*,load,store")])
2062 ;; This pattern builds V64mode constants in integer registers.
2064 [(set (match_operand:V64 0 "register_operand" "")
2065 (match_operand:V64 1 "const_double_or_vector_operand" ""))]
2067 && (GET_CODE (operands[0]) == REG
2068 && REGNO (operands[0]) < 32)
2069 && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2070 && reload_completed"
2071 [(clobber (const_int 0))]
2073 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2077 #if HOST_BITS_PER_WIDE_INT == 32
2080 enum machine_mode mode = GET_MODE (operands[1]);
2081 rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2082 emit_insn (gen_movdi (operands[0], tem));
2087 enum machine_mode mode = GET_MODE (operands[1]);
2088 rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2089 rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2091 gcc_assert (GET_CODE (hi) == CONST_INT);
2092 gcc_assert (GET_CODE (lo) == CONST_INT);
2094 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2096 /* Slick... but this trick loses if this subreg constant part
2097 can be done in one insn. */
2099 && ! SPARC_SETHI32_P (INTVAL (hi))
2100 && ! SPARC_SIMM13_P (INTVAL (hi)))
2102 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2103 gen_highpart (SImode, operands[0])));
2107 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2113 ;; Ok, now the splits to handle all the multi insn and
2114 ;; mis-aligned memory address cases.
2115 ;; In these splits please take note that we must be
2116 ;; careful when V9 but not ARCH64 because the integer
2117 ;; register DFmode cases must be handled.
2119 [(set (match_operand:V64 0 "register_operand" "")
2120 (match_operand:V64 1 "register_operand" ""))]
2123 && ((GET_CODE (operands[0]) == REG
2124 && REGNO (operands[0]) < 32)
2125 || (GET_CODE (operands[0]) == SUBREG
2126 && GET_CODE (SUBREG_REG (operands[0])) == REG
2127 && REGNO (SUBREG_REG (operands[0])) < 32))))
2128 && reload_completed"
2129 [(clobber (const_int 0))]
2131 rtx set_dest = operands[0];
2132 rtx set_src = operands[1];
2135 enum machine_mode half_mode;
2137 /* We can be expanded for DFmode or integral vector modes. */
2138 if (<V64:MODE>mode == DFmode)
2143 dest1 = gen_highpart (half_mode, set_dest);
2144 dest2 = gen_lowpart (half_mode, set_dest);
2145 src1 = gen_highpart (half_mode, set_src);
2146 src2 = gen_lowpart (half_mode, set_src);
2148 /* Now emit using the real source and destination we found, swapping
2149 the order if we detect overlap. */
2150 if (reg_overlap_mentioned_p (dest1, src2))
2152 emit_move_insn_1 (dest2, src2);
2153 emit_move_insn_1 (dest1, src1);
2157 emit_move_insn_1 (dest1, src1);
2158 emit_move_insn_1 (dest2, src2);
2164 [(set (match_operand:V64 0 "register_operand" "")
2165 (match_operand:V64 1 "memory_operand" ""))]
2168 && (((REGNO (operands[0]) % 2) != 0)
2169 || ! mem_min_alignment (operands[1], 8))
2170 && offsettable_memref_p (operands[1])"
2171 [(clobber (const_int 0))]
2173 enum machine_mode half_mode;
2176 /* We can be expanded for DFmode or integral vector modes. */
2177 if (<V64:MODE>mode == DFmode)
2182 word0 = adjust_address (operands[1], half_mode, 0);
2183 word1 = adjust_address (operands[1], half_mode, 4);
2185 if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
2187 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2188 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2192 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2193 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2199 [(set (match_operand:V64 0 "memory_operand" "")
2200 (match_operand:V64 1 "register_operand" ""))]
2203 && (((REGNO (operands[1]) % 2) != 0)
2204 || ! mem_min_alignment (operands[0], 8))
2205 && offsettable_memref_p (operands[0])"
2206 [(clobber (const_int 0))]
2208 enum machine_mode half_mode;
2211 /* We can be expanded for DFmode or integral vector modes. */
2212 if (<V64:MODE>mode == DFmode)
2217 word0 = adjust_address (operands[0], half_mode, 0);
2218 word1 = adjust_address (operands[0], half_mode, 4);
2220 emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
2221 emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
2226 [(set (match_operand:V64 0 "memory_operand" "")
2227 (match_operand:V64 1 "const_zero_operand" ""))]
2231 && ! mem_min_alignment (operands[0], 8)))
2232 && offsettable_memref_p (operands[0])"
2233 [(clobber (const_int 0))]
2235 enum machine_mode half_mode;
2238 /* We can be expanded for DFmode or integral vector modes. */
2239 if (<V64:MODE>mode == DFmode)
2244 dest1 = adjust_address (operands[0], half_mode, 0);
2245 dest2 = adjust_address (operands[0], half_mode, 4);
2247 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2248 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2253 [(set (match_operand:V64 0 "register_operand" "")
2254 (match_operand:V64 1 "const_zero_operand" ""))]
2257 && ((GET_CODE (operands[0]) == REG
2258 && REGNO (operands[0]) < 32)
2259 || (GET_CODE (operands[0]) == SUBREG
2260 && GET_CODE (SUBREG_REG (operands[0])) == REG
2261 && REGNO (SUBREG_REG (operands[0])) < 32))"
2262 [(clobber (const_int 0))]
2264 enum machine_mode half_mode;
2265 rtx set_dest = operands[0];
2268 /* We can be expanded for DFmode or integral vector modes. */
2269 if (<V64:MODE>mode == DFmode)
2274 dest1 = gen_highpart (half_mode, set_dest);
2275 dest2 = gen_lowpart (half_mode, set_dest);
2276 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2277 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2281 (define_expand "movtf"
2282 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2283 (match_operand:TF 1 "general_operand" ""))]
2286 if (sparc_expand_move (TFmode, operands))
2290 (define_insn "*movtf_insn_sp32"
2291 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2292 (match_operand:TF 1 "input_operand" "G,oe,GeUr,o,roG"))]
2295 && (register_operand (operands[0], TFmode)
2296 || register_or_zero_operand (operands[1], TFmode))"
2298 [(set_attr "length" "4")])
2300 ;; Exactly the same as above, except that all `e' cases are deleted.
2301 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2304 (define_insn "*movtf_insn_sp32_no_fpu"
2305 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2306 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
2309 && (register_operand (operands[0], TFmode)
2310 || register_or_zero_operand (operands[1], TFmode))"
2312 [(set_attr "length" "4")])
2314 (define_insn "*movtf_insn_sp64"
2315 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2316 (match_operand:TF 1 "input_operand" "G,oe,Ger,roG"))]
2319 && ! TARGET_HARD_QUAD
2320 && (register_operand (operands[0], TFmode)
2321 || register_or_zero_operand (operands[1], TFmode))"
2323 [(set_attr "length" "2")])
2325 (define_insn "*movtf_insn_sp64_hq"
2326 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2327 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
2331 && (register_operand (operands[0], TFmode)
2332 || register_or_zero_operand (operands[1], TFmode))"
2340 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2341 (set_attr "length" "2,*,*,*,2,2")])
2343 (define_insn "*movtf_insn_sp64_no_fpu"
2344 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2345 (match_operand:TF 1 "input_operand" "orG,rG"))]
2348 && (register_operand (operands[0], TFmode)
2349 || register_or_zero_operand (operands[1], TFmode))"
2351 [(set_attr "length" "2")])
2353 ;; Now all the splits to handle multi-insn TF mode moves.
2355 [(set (match_operand:TF 0 "register_operand" "")
2356 (match_operand:TF 1 "register_operand" ""))]
2360 && ! TARGET_HARD_QUAD)
2361 || ! fp_register_operand (operands[0], TFmode))"
2362 [(clobber (const_int 0))]
2364 rtx set_dest = operands[0];
2365 rtx set_src = operands[1];
2369 dest1 = gen_df_reg (set_dest, 0);
2370 dest2 = gen_df_reg (set_dest, 1);
2371 src1 = gen_df_reg (set_src, 0);
2372 src2 = gen_df_reg (set_src, 1);
2374 /* Now emit using the real source and destination we found, swapping
2375 the order if we detect overlap. */
2376 if (reg_overlap_mentioned_p (dest1, src2))
2378 emit_insn (gen_movdf (dest2, src2));
2379 emit_insn (gen_movdf (dest1, src1));
2383 emit_insn (gen_movdf (dest1, src1));
2384 emit_insn (gen_movdf (dest2, src2));
2390 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2391 (match_operand:TF 1 "const_zero_operand" ""))]
2393 [(clobber (const_int 0))]
2395 rtx set_dest = operands[0];
2398 switch (GET_CODE (set_dest))
2401 dest1 = gen_df_reg (set_dest, 0);
2402 dest2 = gen_df_reg (set_dest, 1);
2405 dest1 = adjust_address (set_dest, DFmode, 0);
2406 dest2 = adjust_address (set_dest, DFmode, 8);
2412 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2413 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2418 [(set (match_operand:TF 0 "register_operand" "")
2419 (match_operand:TF 1 "memory_operand" ""))]
2421 && offsettable_memref_p (operands[1])
2423 || ! TARGET_HARD_QUAD
2424 || ! fp_register_operand (operands[0], TFmode)))"
2425 [(clobber (const_int 0))]
2427 rtx word0 = adjust_address (operands[1], DFmode, 0);
2428 rtx word1 = adjust_address (operands[1], DFmode, 8);
2429 rtx set_dest, dest1, dest2;
2431 set_dest = operands[0];
2433 dest1 = gen_df_reg (set_dest, 0);
2434 dest2 = gen_df_reg (set_dest, 1);
2436 /* Now output, ordering such that we don't clobber any registers
2437 mentioned in the address. */
2438 if (reg_overlap_mentioned_p (dest1, word1))
2441 emit_insn (gen_movdf (dest2, word1));
2442 emit_insn (gen_movdf (dest1, word0));
2446 emit_insn (gen_movdf (dest1, word0));
2447 emit_insn (gen_movdf (dest2, word1));
2453 [(set (match_operand:TF 0 "memory_operand" "")
2454 (match_operand:TF 1 "register_operand" ""))]
2456 && offsettable_memref_p (operands[0])
2458 || ! TARGET_HARD_QUAD
2459 || ! fp_register_operand (operands[1], TFmode)))"
2460 [(clobber (const_int 0))]
2462 rtx set_src = operands[1];
2464 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2465 gen_df_reg (set_src, 0)));
2466 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2467 gen_df_reg (set_src, 1)));
2472 ;; SPARC-V9 conditional move instructions
2474 ;; We can handle larger constants here for some flavors, but for now we keep
2475 ;; it simple and only allow those constants supported by all flavors.
2476 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2477 ;; 3 contains the constant if one is present, but we handle either for
2478 ;; generality (sparc.c puts a constant in operand 2).
2480 (define_expand "mov<I:mode>cc"
2481 [(set (match_operand:I 0 "register_operand" "")
2482 (if_then_else:I (match_operand 1 "comparison_operator" "")
2483 (match_operand:I 2 "arith10_operand" "")
2484 (match_operand:I 3 "arith10_operand" "")))]
2485 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2487 enum rtx_code code = GET_CODE (operands[1]);
2490 if (GET_MODE (XEXP (operands[1], 0)) == DImode
2494 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2496 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2497 GET_CODE (operands[1]));
2499 if (XEXP (operands[1], 1) == const0_rtx
2500 && GET_CODE (XEXP (operands[1], 0)) == REG
2501 && GET_MODE (XEXP (operands[1], 0)) == DImode
2502 && v9_regcmp_p (code))
2503 cc_reg = XEXP (operands[1], 0);
2505 cc_reg = gen_compare_reg (operands[1]);
2507 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2510 (define_expand "mov<F:mode>cc"
2511 [(set (match_operand:F 0 "register_operand" "")
2512 (if_then_else:F (match_operand 1 "comparison_operator" "")
2513 (match_operand:F 2 "register_operand" "")
2514 (match_operand:F 3 "register_operand" "")))]
2515 "TARGET_V9 && TARGET_FPU"
2517 enum rtx_code code = GET_CODE (operands[1]);
2520 if (GET_MODE (XEXP (operands[1], 0)) == DImode
2524 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2526 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2527 GET_CODE (operands[1]));
2529 if (XEXP (operands[1], 1) == const0_rtx
2530 && GET_CODE (XEXP (operands[1], 0)) == REG
2531 && GET_MODE (XEXP (operands[1], 0)) == DImode
2532 && v9_regcmp_p (code))
2533 cc_reg = XEXP (operands[1], 0);
2535 cc_reg = gen_compare_reg (operands[1]);
2537 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2540 ;; Conditional move define_insns
2542 (define_insn "*mov<I:mode>_cc_v9"
2543 [(set (match_operand:I 0 "register_operand" "=r,r")
2544 (if_then_else:I (match_operator 1 "comparison_operator"
2545 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2547 (match_operand:I 3 "arith11_operand" "rL,0")
2548 (match_operand:I 4 "arith11_operand" "0,rL")))]
2549 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2552 mov%c1\t%x2, %4, %0"
2553 [(set_attr "type" "cmove")])
2555 (define_insn "*mov<I:mode>_cc_reg_sp64"
2556 [(set (match_operand:I 0 "register_operand" "=r,r")
2557 (if_then_else:I (match_operator 1 "v9_register_compare_operator"
2558 [(match_operand:DI 2 "register_operand" "r,r")
2560 (match_operand:I 3 "arith10_operand" "rM,0")
2561 (match_operand:I 4 "arith10_operand" "0,rM")))]
2564 movr%D1\t%2, %r3, %0
2565 movr%d1\t%2, %r4, %0"
2566 [(set_attr "type" "cmove")])
2568 (define_insn "*movsf_cc_v9"
2569 [(set (match_operand:SF 0 "register_operand" "=f,f")
2570 (if_then_else:SF (match_operator 1 "comparison_operator"
2571 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2573 (match_operand:SF 3 "register_operand" "f,0")
2574 (match_operand:SF 4 "register_operand" "0,f")))]
2575 "TARGET_V9 && TARGET_FPU"
2577 fmovs%C1\t%x2, %3, %0
2578 fmovs%c1\t%x2, %4, %0"
2579 [(set_attr "type" "fpcmove")])
2581 (define_insn "*movsf_cc_reg_sp64"
2582 [(set (match_operand:SF 0 "register_operand" "=f,f")
2583 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
2584 [(match_operand:DI 2 "register_operand" "r,r")
2586 (match_operand:SF 3 "register_operand" "f,0")
2587 (match_operand:SF 4 "register_operand" "0,f")))]
2588 "TARGET_ARCH64 && TARGET_FPU"
2590 fmovrs%D1\t%2, %3, %0
2591 fmovrs%d1\t%2, %4, %0"
2592 [(set_attr "type" "fpcrmove")])
2594 ;; Named because invoked by movtf_cc_v9
2595 (define_insn "movdf_cc_v9"
2596 [(set (match_operand:DF 0 "register_operand" "=e,e")
2597 (if_then_else:DF (match_operator 1 "comparison_operator"
2598 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2600 (match_operand:DF 3 "register_operand" "e,0")
2601 (match_operand:DF 4 "register_operand" "0,e")))]
2602 "TARGET_V9 && TARGET_FPU"
2604 fmovd%C1\t%x2, %3, %0
2605 fmovd%c1\t%x2, %4, %0"
2606 [(set_attr "type" "fpcmove")
2607 (set_attr "fptype" "double")])
2609 ;; Named because invoked by movtf_cc_reg_sp64
2610 (define_insn "movdf_cc_reg_sp64"
2611 [(set (match_operand:DF 0 "register_operand" "=e,e")
2612 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
2613 [(match_operand:DI 2 "register_operand" "r,r")
2615 (match_operand:DF 3 "register_operand" "e,0")
2616 (match_operand:DF 4 "register_operand" "0,e")))]
2617 "TARGET_ARCH64 && TARGET_FPU"
2619 fmovrd%D1\t%2, %3, %0
2620 fmovrd%d1\t%2, %4, %0"
2621 [(set_attr "type" "fpcrmove")
2622 (set_attr "fptype" "double")])
2624 (define_insn "*movtf_cc_hq_v9"
2625 [(set (match_operand:TF 0 "register_operand" "=e,e")
2626 (if_then_else:TF (match_operator 1 "comparison_operator"
2627 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2629 (match_operand:TF 3 "register_operand" "e,0")
2630 (match_operand:TF 4 "register_operand" "0,e")))]
2631 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2633 fmovq%C1\t%x2, %3, %0
2634 fmovq%c1\t%x2, %4, %0"
2635 [(set_attr "type" "fpcmove")])
2637 (define_insn "*movtf_cc_reg_hq_sp64"
2638 [(set (match_operand:TF 0 "register_operand" "=e,e")
2639 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2640 [(match_operand:DI 2 "register_operand" "r,r")
2642 (match_operand:TF 3 "register_operand" "e,0")
2643 (match_operand:TF 4 "register_operand" "0,e")))]
2644 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
2646 fmovrq%D1\t%2, %3, %0
2647 fmovrq%d1\t%2, %4, %0"
2648 [(set_attr "type" "fpcrmove")])
2650 (define_insn_and_split "*movtf_cc_v9"
2651 [(set (match_operand:TF 0 "register_operand" "=e,e")
2652 (if_then_else:TF (match_operator 1 "comparison_operator"
2653 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2655 (match_operand:TF 3 "register_operand" "e,0")
2656 (match_operand:TF 4 "register_operand" "0,e")))]
2657 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
2659 "&& reload_completed"
2660 [(clobber (const_int 0))]
2662 rtx set_dest = operands[0];
2663 rtx set_srca = operands[3];
2664 rtx set_srcb = operands[4];
2665 int third = rtx_equal_p (set_dest, set_srca);
2667 rtx srca1, srca2, srcb1, srcb2;
2669 dest1 = gen_df_reg (set_dest, 0);
2670 dest2 = gen_df_reg (set_dest, 1);
2671 srca1 = gen_df_reg (set_srca, 0);
2672 srca2 = gen_df_reg (set_srca, 1);
2673 srcb1 = gen_df_reg (set_srcb, 0);
2674 srcb2 = gen_df_reg (set_srcb, 1);
2676 /* Now emit using the real source and destination we found, swapping
2677 the order if we detect overlap. */
2678 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2679 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2681 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2682 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2686 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2687 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2691 [(set_attr "length" "2")])
2693 (define_insn_and_split "*movtf_cc_reg_sp64"
2694 [(set (match_operand:TF 0 "register_operand" "=e,e")
2695 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2696 [(match_operand:DI 2 "register_operand" "r,r")
2698 (match_operand:TF 3 "register_operand" "e,0")
2699 (match_operand:TF 4 "register_operand" "0,e")))]
2700 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
2702 "&& reload_completed"
2703 [(clobber (const_int 0))]
2705 rtx set_dest = operands[0];
2706 rtx set_srca = operands[3];
2707 rtx set_srcb = operands[4];
2708 int third = rtx_equal_p (set_dest, set_srca);
2710 rtx srca1, srca2, srcb1, srcb2;
2712 dest1 = gen_df_reg (set_dest, 0);
2713 dest2 = gen_df_reg (set_dest, 1);
2714 srca1 = gen_df_reg (set_srca, 0);
2715 srca2 = gen_df_reg (set_srca, 1);
2716 srcb1 = gen_df_reg (set_srcb, 0);
2717 srcb2 = gen_df_reg (set_srcb, 1);
2719 /* Now emit using the real source and destination we found, swapping
2720 the order if we detect overlap. */
2721 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2722 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2724 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2725 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2729 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2730 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2734 [(set_attr "length" "2")])
2737 ;; Zero-extension instructions
2739 ;; These patterns originally accepted general_operands, however, slightly
2740 ;; better code is generated by only accepting register_operands, and then
2741 ;; letting combine generate the ldu[hb] insns.
2743 (define_expand "zero_extendhisi2"
2744 [(set (match_operand:SI 0 "register_operand" "")
2745 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2748 rtx temp = gen_reg_rtx (SImode);
2749 rtx shift_16 = GEN_INT (16);
2750 int op1_subbyte = 0;
2752 if (GET_CODE (operand1) == SUBREG)
2754 op1_subbyte = SUBREG_BYTE (operand1);
2755 op1_subbyte /= GET_MODE_SIZE (SImode);
2756 op1_subbyte *= GET_MODE_SIZE (SImode);
2757 operand1 = XEXP (operand1, 0);
2760 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2762 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2766 (define_insn "*zero_extendhisi2_insn"
2767 [(set (match_operand:SI 0 "register_operand" "=r")
2768 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2771 [(set_attr "type" "load")
2772 (set_attr "us3load_type" "3cycle")])
2774 (define_expand "zero_extendqihi2"
2775 [(set (match_operand:HI 0 "register_operand" "")
2776 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2780 (define_insn "*zero_extendqihi2_insn"
2781 [(set (match_operand:HI 0 "register_operand" "=r,r")
2782 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
2783 "GET_CODE (operands[1]) != CONST_INT"
2787 [(set_attr "type" "*,load")
2788 (set_attr "us3load_type" "*,3cycle")])
2790 (define_expand "zero_extendqisi2"
2791 [(set (match_operand:SI 0 "register_operand" "")
2792 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2796 (define_insn "*zero_extendqisi2_insn"
2797 [(set (match_operand:SI 0 "register_operand" "=r,r")
2798 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
2799 "GET_CODE (operands[1]) != CONST_INT"
2803 [(set_attr "type" "*,load")
2804 (set_attr "us3load_type" "*,3cycle")])
2806 (define_expand "zero_extendqidi2"
2807 [(set (match_operand:DI 0 "register_operand" "")
2808 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2812 (define_insn "*zero_extendqidi2_insn"
2813 [(set (match_operand:DI 0 "register_operand" "=r,r")
2814 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
2815 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2819 [(set_attr "type" "*,load")
2820 (set_attr "us3load_type" "*,3cycle")])
2822 (define_expand "zero_extendhidi2"
2823 [(set (match_operand:DI 0 "register_operand" "")
2824 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2827 rtx temp = gen_reg_rtx (DImode);
2828 rtx shift_48 = GEN_INT (48);
2829 int op1_subbyte = 0;
2831 if (GET_CODE (operand1) == SUBREG)
2833 op1_subbyte = SUBREG_BYTE (operand1);
2834 op1_subbyte /= GET_MODE_SIZE (DImode);
2835 op1_subbyte *= GET_MODE_SIZE (DImode);
2836 operand1 = XEXP (operand1, 0);
2839 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
2841 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
2845 (define_insn "*zero_extendhidi2_insn"
2846 [(set (match_operand:DI 0 "register_operand" "=r")
2847 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2850 [(set_attr "type" "load")
2851 (set_attr "us3load_type" "3cycle")])
2853 ;; ??? Write truncdisi pattern using sra?
2855 (define_expand "zero_extendsidi2"
2856 [(set (match_operand:DI 0 "register_operand" "")
2857 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
2861 (define_insn "*zero_extendsidi2_insn_sp64"
2862 [(set (match_operand:DI 0 "register_operand" "=r,r")
2863 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
2864 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2868 [(set_attr "type" "shift,load")])
2870 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
2871 [(set (match_operand:DI 0 "register_operand" "=r")
2872 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
2875 "&& reload_completed"
2876 [(set (match_dup 2) (match_dup 3))
2877 (set (match_dup 4) (match_dup 5))]
2881 dest1 = gen_highpart (SImode, operands[0]);
2882 dest2 = gen_lowpart (SImode, operands[0]);
2884 /* Swap the order in case of overlap. */
2885 if (REGNO (dest1) == REGNO (operands[1]))
2887 operands[2] = dest2;
2888 operands[3] = operands[1];
2889 operands[4] = dest1;
2890 operands[5] = const0_rtx;
2894 operands[2] = dest1;
2895 operands[3] = const0_rtx;
2896 operands[4] = dest2;
2897 operands[5] = operands[1];
2900 [(set_attr "length" "2")])
2902 ;; Simplify comparisons of extended values.
2904 (define_insn "*cmp_zero_extendqisi2"
2906 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
2909 "andcc\t%0, 0xff, %%g0"
2910 [(set_attr "type" "compare")])
2912 (define_insn "*cmp_zero_qi"
2914 (compare:CC (match_operand:QI 0 "register_operand" "r")
2917 "andcc\t%0, 0xff, %%g0"
2918 [(set_attr "type" "compare")])
2920 (define_insn "*cmp_zero_extendqisi2_set"
2922 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
2924 (set (match_operand:SI 0 "register_operand" "=r")
2925 (zero_extend:SI (match_dup 1)))]
2927 "andcc\t%1, 0xff, %0"
2928 [(set_attr "type" "compare")])
2930 (define_insn "*cmp_zero_extendqisi2_andcc_set"
2932 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
2935 (set (match_operand:SI 0 "register_operand" "=r")
2936 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
2938 "andcc\t%1, 0xff, %0"
2939 [(set_attr "type" "compare")])
2941 (define_insn "*cmp_zero_extendqidi2"
2943 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
2946 "andcc\t%0, 0xff, %%g0"
2947 [(set_attr "type" "compare")])
2949 (define_insn "*cmp_zero_qi_sp64"
2951 (compare:CCX (match_operand:QI 0 "register_operand" "r")
2954 "andcc\t%0, 0xff, %%g0"
2955 [(set_attr "type" "compare")])
2957 (define_insn "*cmp_zero_extendqidi2_set"
2959 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
2961 (set (match_operand:DI 0 "register_operand" "=r")
2962 (zero_extend:DI (match_dup 1)))]
2964 "andcc\t%1, 0xff, %0"
2965 [(set_attr "type" "compare")])
2967 (define_insn "*cmp_zero_extendqidi2_andcc_set"
2969 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
2972 (set (match_operand:DI 0 "register_operand" "=r")
2973 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
2975 "andcc\t%1, 0xff, %0"
2976 [(set_attr "type" "compare")])
2978 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
2980 (define_insn "*cmp_siqi_trunc"
2982 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
2985 "andcc\t%0, 0xff, %%g0"
2986 [(set_attr "type" "compare")])
2988 (define_insn "*cmp_siqi_trunc_set"
2990 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
2992 (set (match_operand:QI 0 "register_operand" "=r")
2993 (subreg:QI (match_dup 1) 3))]
2995 "andcc\t%1, 0xff, %0"
2996 [(set_attr "type" "compare")])
2998 (define_insn "*cmp_diqi_trunc"
3000 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3003 "andcc\t%0, 0xff, %%g0"
3004 [(set_attr "type" "compare")])
3006 (define_insn "*cmp_diqi_trunc_set"
3008 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3010 (set (match_operand:QI 0 "register_operand" "=r")
3011 (subreg:QI (match_dup 1) 7))]
3013 "andcc\t%1, 0xff, %0"
3014 [(set_attr "type" "compare")])
3017 ;; Sign-extension instructions
3019 ;; These patterns originally accepted general_operands, however, slightly
3020 ;; better code is generated by only accepting register_operands, and then
3021 ;; letting combine generate the lds[hb] insns.
3023 (define_expand "extendhisi2"
3024 [(set (match_operand:SI 0 "register_operand" "")
3025 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3028 rtx temp = gen_reg_rtx (SImode);
3029 rtx shift_16 = GEN_INT (16);
3030 int op1_subbyte = 0;
3032 if (GET_CODE (operand1) == SUBREG)
3034 op1_subbyte = SUBREG_BYTE (operand1);
3035 op1_subbyte /= GET_MODE_SIZE (SImode);
3036 op1_subbyte *= GET_MODE_SIZE (SImode);
3037 operand1 = XEXP (operand1, 0);
3040 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3042 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3046 (define_insn "*sign_extendhisi2_insn"
3047 [(set (match_operand:SI 0 "register_operand" "=r")
3048 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3051 [(set_attr "type" "sload")
3052 (set_attr "us3load_type" "3cycle")])
3054 (define_expand "extendqihi2"
3055 [(set (match_operand:HI 0 "register_operand" "")
3056 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3059 rtx temp = gen_reg_rtx (SImode);
3060 rtx shift_24 = GEN_INT (24);
3061 int op1_subbyte = 0;
3062 int op0_subbyte = 0;
3064 if (GET_CODE (operand1) == SUBREG)
3066 op1_subbyte = SUBREG_BYTE (operand1);
3067 op1_subbyte /= GET_MODE_SIZE (SImode);
3068 op1_subbyte *= GET_MODE_SIZE (SImode);
3069 operand1 = XEXP (operand1, 0);
3071 if (GET_CODE (operand0) == SUBREG)
3073 op0_subbyte = SUBREG_BYTE (operand0);
3074 op0_subbyte /= GET_MODE_SIZE (SImode);
3075 op0_subbyte *= GET_MODE_SIZE (SImode);
3076 operand0 = XEXP (operand0, 0);
3078 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3080 if (GET_MODE (operand0) != SImode)
3081 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3082 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3086 (define_insn "*sign_extendqihi2_insn"
3087 [(set (match_operand:HI 0 "register_operand" "=r")
3088 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3091 [(set_attr "type" "sload")
3092 (set_attr "us3load_type" "3cycle")])
3094 (define_expand "extendqisi2"
3095 [(set (match_operand:SI 0 "register_operand" "")
3096 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3099 rtx temp = gen_reg_rtx (SImode);
3100 rtx shift_24 = GEN_INT (24);
3101 int op1_subbyte = 0;
3103 if (GET_CODE (operand1) == SUBREG)
3105 op1_subbyte = SUBREG_BYTE (operand1);
3106 op1_subbyte /= GET_MODE_SIZE (SImode);
3107 op1_subbyte *= GET_MODE_SIZE (SImode);
3108 operand1 = XEXP (operand1, 0);
3111 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3113 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3117 (define_insn "*sign_extendqisi2_insn"
3118 [(set (match_operand:SI 0 "register_operand" "=r")
3119 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3122 [(set_attr "type" "sload")
3123 (set_attr "us3load_type" "3cycle")])
3125 (define_expand "extendqidi2"
3126 [(set (match_operand:DI 0 "register_operand" "")
3127 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3130 rtx temp = gen_reg_rtx (DImode);
3131 rtx shift_56 = GEN_INT (56);
3132 int op1_subbyte = 0;
3134 if (GET_CODE (operand1) == SUBREG)
3136 op1_subbyte = SUBREG_BYTE (operand1);
3137 op1_subbyte /= GET_MODE_SIZE (DImode);
3138 op1_subbyte *= GET_MODE_SIZE (DImode);
3139 operand1 = XEXP (operand1, 0);
3142 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3144 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3148 (define_insn "*sign_extendqidi2_insn"
3149 [(set (match_operand:DI 0 "register_operand" "=r")
3150 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3153 [(set_attr "type" "sload")
3154 (set_attr "us3load_type" "3cycle")])
3156 (define_expand "extendhidi2"
3157 [(set (match_operand:DI 0 "register_operand" "")
3158 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3161 rtx temp = gen_reg_rtx (DImode);
3162 rtx shift_48 = GEN_INT (48);
3163 int op1_subbyte = 0;
3165 if (GET_CODE (operand1) == SUBREG)
3167 op1_subbyte = SUBREG_BYTE (operand1);
3168 op1_subbyte /= GET_MODE_SIZE (DImode);
3169 op1_subbyte *= GET_MODE_SIZE (DImode);
3170 operand1 = XEXP (operand1, 0);
3173 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3175 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3179 (define_insn "*sign_extendhidi2_insn"
3180 [(set (match_operand:DI 0 "register_operand" "=r")
3181 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3184 [(set_attr "type" "sload")
3185 (set_attr "us3load_type" "3cycle")])
3187 (define_expand "extendsidi2"
3188 [(set (match_operand:DI 0 "register_operand" "")
3189 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3193 (define_insn "*sign_extendsidi2_insn"
3194 [(set (match_operand:DI 0 "register_operand" "=r,r")
3195 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3200 [(set_attr "type" "shift,sload")
3201 (set_attr "us3load_type" "*,3cycle")])
3204 ;; Special pattern for optimizing bit-field compares. This is needed
3205 ;; because combine uses this as a canonical form.
3207 (define_insn "*cmp_zero_extract"
3210 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3211 (match_operand:SI 1 "small_int_operand" "I")
3212 (match_operand:SI 2 "small_int_operand" "I"))
3214 "INTVAL (operands[2]) > 19"
3216 int len = INTVAL (operands[1]);
3217 int pos = 32 - INTVAL (operands[2]) - len;
3218 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3219 operands[1] = GEN_INT (mask);
3220 return "andcc\t%0, %1, %%g0";
3222 [(set_attr "type" "compare")])
3224 (define_insn "*cmp_zero_extract_sp64"
3227 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3228 (match_operand:SI 1 "small_int_operand" "I")
3229 (match_operand:SI 2 "small_int_operand" "I"))
3231 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3233 int len = INTVAL (operands[1]);
3234 int pos = 64 - INTVAL (operands[2]) - len;
3235 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3236 operands[1] = GEN_INT (mask);
3237 return "andcc\t%0, %1, %%g0";
3239 [(set_attr "type" "compare")])
3242 ;; Conversions between float, double and long double.
3244 (define_insn "extendsfdf2"
3245 [(set (match_operand:DF 0 "register_operand" "=e")
3247 (match_operand:SF 1 "register_operand" "f")))]
3250 [(set_attr "type" "fp")
3251 (set_attr "fptype" "double")])
3253 (define_expand "extendsftf2"
3254 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3256 (match_operand:SF 1 "register_operand" "")))]
3257 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3258 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3260 (define_insn "*extendsftf2_hq"
3261 [(set (match_operand:TF 0 "register_operand" "=e")
3263 (match_operand:SF 1 "register_operand" "f")))]
3264 "TARGET_FPU && TARGET_HARD_QUAD"
3266 [(set_attr "type" "fp")])
3268 (define_expand "extenddftf2"
3269 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3271 (match_operand:DF 1 "register_operand" "")))]
3272 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3273 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3275 (define_insn "*extenddftf2_hq"
3276 [(set (match_operand:TF 0 "register_operand" "=e")
3278 (match_operand:DF 1 "register_operand" "e")))]
3279 "TARGET_FPU && TARGET_HARD_QUAD"
3281 [(set_attr "type" "fp")])
3283 (define_insn "truncdfsf2"
3284 [(set (match_operand:SF 0 "register_operand" "=f")
3286 (match_operand:DF 1 "register_operand" "e")))]
3289 [(set_attr "type" "fp")
3290 (set_attr "fptype" "double")])
3292 (define_expand "trunctfsf2"
3293 [(set (match_operand:SF 0 "register_operand" "")
3295 (match_operand:TF 1 "general_operand" "")))]
3296 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3297 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3299 (define_insn "*trunctfsf2_hq"
3300 [(set (match_operand:SF 0 "register_operand" "=f")
3302 (match_operand:TF 1 "register_operand" "e")))]
3303 "TARGET_FPU && TARGET_HARD_QUAD"
3305 [(set_attr "type" "fp")])
3307 (define_expand "trunctfdf2"
3308 [(set (match_operand:DF 0 "register_operand" "")
3310 (match_operand:TF 1 "general_operand" "")))]
3311 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3312 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3314 (define_insn "*trunctfdf2_hq"
3315 [(set (match_operand:DF 0 "register_operand" "=e")
3317 (match_operand:TF 1 "register_operand" "e")))]
3318 "TARGET_FPU && TARGET_HARD_QUAD"
3320 [(set_attr "type" "fp")])
3323 ;; Conversion between fixed point and floating point.
3325 (define_insn "floatsisf2"
3326 [(set (match_operand:SF 0 "register_operand" "=f")
3327 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3330 [(set_attr "type" "fp")
3331 (set_attr "fptype" "double")])
3333 (define_insn "floatsidf2"
3334 [(set (match_operand:DF 0 "register_operand" "=e")
3335 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3338 [(set_attr "type" "fp")
3339 (set_attr "fptype" "double")])
3341 (define_expand "floatsitf2"
3342 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3343 (float:TF (match_operand:SI 1 "register_operand" "")))]
3344 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3345 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3347 (define_insn "*floatsitf2_hq"
3348 [(set (match_operand:TF 0 "register_operand" "=e")
3349 (float:TF (match_operand:SI 1 "register_operand" "f")))]
3350 "TARGET_FPU && TARGET_HARD_QUAD"
3352 [(set_attr "type" "fp")])
3354 (define_expand "floatunssitf2"
3355 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3356 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3357 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3358 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3360 ;; Now the same for 64 bit sources.
3362 (define_insn "floatdisf2"
3363 [(set (match_operand:SF 0 "register_operand" "=f")
3364 (float:SF (match_operand:DI 1 "register_operand" "e")))]
3365 "TARGET_V9 && TARGET_FPU"
3367 [(set_attr "type" "fp")
3368 (set_attr "fptype" "double")])
3370 (define_expand "floatunsdisf2"
3371 [(use (match_operand:SF 0 "register_operand" ""))
3372 (use (match_operand:DI 1 "general_operand" ""))]
3373 "TARGET_ARCH64 && TARGET_FPU"
3374 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3376 (define_insn "floatdidf2"
3377 [(set (match_operand:DF 0 "register_operand" "=e")
3378 (float:DF (match_operand:DI 1 "register_operand" "e")))]
3379 "TARGET_V9 && TARGET_FPU"
3381 [(set_attr "type" "fp")
3382 (set_attr "fptype" "double")])
3384 (define_expand "floatunsdidf2"
3385 [(use (match_operand:DF 0 "register_operand" ""))
3386 (use (match_operand:DI 1 "general_operand" ""))]
3387 "TARGET_ARCH64 && TARGET_FPU"
3388 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3390 (define_expand "floatditf2"
3391 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3392 (float:TF (match_operand:DI 1 "register_operand" "")))]
3393 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3394 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3396 (define_insn "*floatditf2_hq"
3397 [(set (match_operand:TF 0 "register_operand" "=e")
3398 (float:TF (match_operand:DI 1 "register_operand" "e")))]
3399 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3401 [(set_attr "type" "fp")])
3403 (define_expand "floatunsditf2"
3404 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3405 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3406 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3407 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3409 ;; Convert a float to an actual integer.
3410 ;; Truncation is performed as part of the conversion.
3412 (define_insn "fix_truncsfsi2"
3413 [(set (match_operand:SI 0 "register_operand" "=f")
3414 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3417 [(set_attr "type" "fp")
3418 (set_attr "fptype" "double")])
3420 (define_insn "fix_truncdfsi2"
3421 [(set (match_operand:SI 0 "register_operand" "=f")
3422 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3425 [(set_attr "type" "fp")
3426 (set_attr "fptype" "double")])
3428 (define_expand "fix_trunctfsi2"
3429 [(set (match_operand:SI 0 "register_operand" "")
3430 (fix:SI (match_operand:TF 1 "general_operand" "")))]
3431 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3432 "emit_tfmode_cvt (FIX, operands); DONE;")
3434 (define_insn "*fix_trunctfsi2_hq"
3435 [(set (match_operand:SI 0 "register_operand" "=f")
3436 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
3437 "TARGET_FPU && TARGET_HARD_QUAD"
3439 [(set_attr "type" "fp")])
3441 (define_expand "fixuns_trunctfsi2"
3442 [(set (match_operand:SI 0 "register_operand" "")
3443 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
3444 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3445 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3447 ;; Now the same, for V9 targets
3449 (define_insn "fix_truncsfdi2"
3450 [(set (match_operand:DI 0 "register_operand" "=e")
3451 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3452 "TARGET_V9 && TARGET_FPU"
3454 [(set_attr "type" "fp")
3455 (set_attr "fptype" "double")])
3457 (define_expand "fixuns_truncsfdi2"
3458 [(use (match_operand:DI 0 "register_operand" ""))
3459 (use (match_operand:SF 1 "general_operand" ""))]
3460 "TARGET_ARCH64 && TARGET_FPU"
3461 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
3463 (define_insn "fix_truncdfdi2"
3464 [(set (match_operand:DI 0 "register_operand" "=e")
3465 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3466 "TARGET_V9 && TARGET_FPU"
3468 [(set_attr "type" "fp")
3469 (set_attr "fptype" "double")])
3471 (define_expand "fixuns_truncdfdi2"
3472 [(use (match_operand:DI 0 "register_operand" ""))
3473 (use (match_operand:DF 1 "general_operand" ""))]
3474 "TARGET_ARCH64 && TARGET_FPU"
3475 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
3477 (define_expand "fix_trunctfdi2"
3478 [(set (match_operand:DI 0 "register_operand" "")
3479 (fix:DI (match_operand:TF 1 "general_operand" "")))]
3480 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3481 "emit_tfmode_cvt (FIX, operands); DONE;")
3483 (define_insn "*fix_trunctfdi2_hq"
3484 [(set (match_operand:DI 0 "register_operand" "=e")
3485 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
3486 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3488 [(set_attr "type" "fp")])
3490 (define_expand "fixuns_trunctfdi2"
3491 [(set (match_operand:DI 0 "register_operand" "")
3492 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
3493 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3494 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3497 ;; Integer addition/subtraction instructions.
3499 (define_expand "adddi3"
3500 [(set (match_operand:DI 0 "register_operand" "")
3501 (plus:DI (match_operand:DI 1 "register_operand" "")
3502 (match_operand:DI 2 "arith_double_add_operand" "")))]
3505 if (! TARGET_ARCH64)
3507 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3508 gen_rtx_SET (VOIDmode, operands[0],
3509 gen_rtx_PLUS (DImode, operands[1],
3511 gen_rtx_CLOBBER (VOIDmode,
3512 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3517 (define_insn_and_split "*adddi3_insn_sp32"
3518 [(set (match_operand:DI 0 "register_operand" "=r")
3519 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3520 (match_operand:DI 2 "arith_double_operand" "rHI")))
3521 (clobber (reg:CC 100))]
3524 "&& reload_completed"
3525 [(parallel [(set (reg:CC_NOOV 100)
3526 (compare:CC_NOOV (plus:SI (match_dup 4)
3530 (plus:SI (match_dup 4) (match_dup 5)))])
3532 (plus:SI (plus:SI (match_dup 7)
3534 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3536 operands[3] = gen_lowpart (SImode, operands[0]);
3537 operands[4] = gen_lowpart (SImode, operands[1]);
3538 operands[5] = gen_lowpart (SImode, operands[2]);
3539 operands[6] = gen_highpart (SImode, operands[0]);
3540 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3541 #if HOST_BITS_PER_WIDE_INT == 32
3542 if (GET_CODE (operands[2]) == CONST_INT)
3544 if (INTVAL (operands[2]) < 0)
3545 operands[8] = constm1_rtx;
3547 operands[8] = const0_rtx;
3551 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3553 [(set_attr "length" "2")])
3555 ;; LTU here means "carry set"
3557 [(set (match_operand:SI 0 "register_operand" "=r")
3558 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3559 (match_operand:SI 2 "arith_operand" "rI"))
3560 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3563 [(set_attr "type" "ialuX")])
3565 (define_insn_and_split "*addx_extend_sp32"
3566 [(set (match_operand:DI 0 "register_operand" "=r")
3567 (zero_extend:DI (plus:SI (plus:SI
3568 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3569 (match_operand:SI 2 "arith_operand" "rI"))
3570 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3573 "&& reload_completed"
3574 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
3575 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
3576 (set (match_dup 4) (const_int 0))]
3577 "operands[3] = gen_lowpart (SImode, operands[0]);
3578 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
3579 [(set_attr "length" "2")])
3581 (define_insn "*addx_extend_sp64"
3582 [(set (match_operand:DI 0 "register_operand" "=r")
3583 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3584 (match_operand:SI 2 "arith_operand" "rI"))
3585 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3588 [(set_attr "type" "ialuX")])
3590 (define_insn_and_split "*adddi3_extend_sp32"
3591 [(set (match_operand:DI 0 "register_operand" "=r")
3592 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3593 (match_operand:DI 2 "register_operand" "r")))
3594 (clobber (reg:CC 100))]
3597 "&& reload_completed"
3598 [(parallel [(set (reg:CC_NOOV 100)
3599 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
3601 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
3603 (plus:SI (plus:SI (match_dup 4) (const_int 0))
3604 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3605 "operands[3] = gen_lowpart (SImode, operands[2]);
3606 operands[4] = gen_highpart (SImode, operands[2]);
3607 operands[5] = gen_lowpart (SImode, operands[0]);
3608 operands[6] = gen_highpart (SImode, operands[0]);"
3609 [(set_attr "length" "2")])
3611 (define_insn "*adddi3_sp64"
3612 [(set (match_operand:DI 0 "register_operand" "=r,r")
3613 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3614 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3620 (define_insn "addsi3"
3621 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3622 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
3623 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3628 fpadd32s\t%1, %2, %0"
3629 [(set_attr "type" "*,*,fga")
3630 (set_attr "fptype" "*,*,single")])
3632 (define_insn "*cmp_cc_plus"
3633 [(set (reg:CC_NOOV 100)
3634 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3635 (match_operand:SI 1 "arith_operand" "rI"))
3638 "addcc\t%0, %1, %%g0"
3639 [(set_attr "type" "compare")])
3641 (define_insn "*cmp_ccx_plus"
3642 [(set (reg:CCX_NOOV 100)
3643 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
3644 (match_operand:DI 1 "arith_operand" "rI"))
3647 "addcc\t%0, %1, %%g0"
3648 [(set_attr "type" "compare")])
3650 (define_insn "*cmp_cc_plus_set"
3651 [(set (reg:CC_NOOV 100)
3652 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3653 (match_operand:SI 2 "arith_operand" "rI"))
3655 (set (match_operand:SI 0 "register_operand" "=r")
3656 (plus:SI (match_dup 1) (match_dup 2)))]
3659 [(set_attr "type" "compare")])
3661 (define_insn "*cmp_ccx_plus_set"
3662 [(set (reg:CCX_NOOV 100)
3663 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
3664 (match_operand:DI 2 "arith_operand" "rI"))
3666 (set (match_operand:DI 0 "register_operand" "=r")
3667 (plus:DI (match_dup 1) (match_dup 2)))]
3670 [(set_attr "type" "compare")])
3672 (define_expand "subdi3"
3673 [(set (match_operand:DI 0 "register_operand" "")
3674 (minus:DI (match_operand:DI 1 "register_operand" "")
3675 (match_operand:DI 2 "arith_double_add_operand" "")))]
3678 if (! TARGET_ARCH64)
3680 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3681 gen_rtx_SET (VOIDmode, operands[0],
3682 gen_rtx_MINUS (DImode, operands[1],
3684 gen_rtx_CLOBBER (VOIDmode,
3685 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3690 (define_insn_and_split "*subdi3_insn_sp32"
3691 [(set (match_operand:DI 0 "register_operand" "=r")
3692 (minus:DI (match_operand:DI 1 "register_operand" "r")
3693 (match_operand:DI 2 "arith_double_operand" "rHI")))
3694 (clobber (reg:CC 100))]
3697 "&& reload_completed"
3698 [(parallel [(set (reg:CC_NOOV 100)
3699 (compare:CC_NOOV (minus:SI (match_dup 4)
3703 (minus:SI (match_dup 4) (match_dup 5)))])
3705 (minus:SI (minus:SI (match_dup 7)
3707 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3709 operands[3] = gen_lowpart (SImode, operands[0]);
3710 operands[4] = gen_lowpart (SImode, operands[1]);
3711 operands[5] = gen_lowpart (SImode, operands[2]);
3712 operands[6] = gen_highpart (SImode, operands[0]);
3713 operands[7] = gen_highpart (SImode, operands[1]);
3714 #if HOST_BITS_PER_WIDE_INT == 32
3715 if (GET_CODE (operands[2]) == CONST_INT)
3717 if (INTVAL (operands[2]) < 0)
3718 operands[8] = constm1_rtx;
3720 operands[8] = const0_rtx;
3724 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3726 [(set_attr "length" "2")])
3728 ;; LTU here means "carry set"
3730 [(set (match_operand:SI 0 "register_operand" "=r")
3731 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3732 (match_operand:SI 2 "arith_operand" "rI"))
3733 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3736 [(set_attr "type" "ialuX")])
3738 (define_insn "*subx_extend_sp64"
3739 [(set (match_operand:DI 0 "register_operand" "=r")
3740 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3741 (match_operand:SI 2 "arith_operand" "rI"))
3742 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3745 [(set_attr "type" "ialuX")])
3747 (define_insn_and_split "*subx_extend"
3748 [(set (match_operand:DI 0 "register_operand" "=r")
3749 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3750 (match_operand:SI 2 "arith_operand" "rI"))
3751 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3754 "&& reload_completed"
3755 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
3756 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
3757 (set (match_dup 4) (const_int 0))]
3758 "operands[3] = gen_lowpart (SImode, operands[0]);
3759 operands[4] = gen_highpart (SImode, operands[0]);"
3760 [(set_attr "length" "2")])
3762 (define_insn_and_split "*subdi3_extend_sp32"
3763 [(set (match_operand:DI 0 "register_operand" "=r")
3764 (minus:DI (match_operand:DI 1 "register_operand" "r")
3765 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
3766 (clobber (reg:CC 100))]
3769 "&& reload_completed"
3770 [(parallel [(set (reg:CC_NOOV 100)
3771 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
3773 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
3775 (minus:SI (minus:SI (match_dup 4) (const_int 0))
3776 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3777 "operands[3] = gen_lowpart (SImode, operands[1]);
3778 operands[4] = gen_highpart (SImode, operands[1]);
3779 operands[5] = gen_lowpart (SImode, operands[0]);
3780 operands[6] = gen_highpart (SImode, operands[0]);"
3781 [(set_attr "length" "2")])
3783 (define_insn "*subdi3_sp64"
3784 [(set (match_operand:DI 0 "register_operand" "=r,r")
3785 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
3786 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3792 (define_insn "subsi3"
3793 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3794 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
3795 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3800 fpsub32s\t%1, %2, %0"
3801 [(set_attr "type" "*,*,fga")
3802 (set_attr "fptype" "*,*,single")])
3804 (define_insn "*cmp_minus_cc"
3805 [(set (reg:CC_NOOV 100)
3806 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
3807 (match_operand:SI 1 "arith_operand" "rI"))
3810 "subcc\t%r0, %1, %%g0"
3811 [(set_attr "type" "compare")])
3813 (define_insn "*cmp_minus_ccx"
3814 [(set (reg:CCX_NOOV 100)
3815 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
3816 (match_operand:DI 1 "arith_operand" "rI"))
3819 "subcc\t%0, %1, %%g0"
3820 [(set_attr "type" "compare")])
3822 (define_insn "cmp_minus_cc_set"
3823 [(set (reg:CC_NOOV 100)
3824 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3825 (match_operand:SI 2 "arith_operand" "rI"))
3827 (set (match_operand:SI 0 "register_operand" "=r")
3828 (minus:SI (match_dup 1) (match_dup 2)))]
3830 "subcc\t%r1, %2, %0"
3831 [(set_attr "type" "compare")])
3833 (define_insn "*cmp_minus_ccx_set"
3834 [(set (reg:CCX_NOOV 100)
3835 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
3836 (match_operand:DI 2 "arith_operand" "rI"))
3838 (set (match_operand:DI 0 "register_operand" "=r")
3839 (minus:DI (match_dup 1) (match_dup 2)))]
3842 [(set_attr "type" "compare")])
3845 ;; Integer multiply/divide instructions.
3847 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
3848 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
3850 (define_insn "mulsi3"
3851 [(set (match_operand:SI 0 "register_operand" "=r")
3852 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3853 (match_operand:SI 2 "arith_operand" "rI")))]
3856 [(set_attr "type" "imul")])
3858 (define_expand "muldi3"
3859 [(set (match_operand:DI 0 "register_operand" "")
3860 (mult:DI (match_operand:DI 1 "arith_operand" "")
3861 (match_operand:DI 2 "arith_operand" "")))]
3862 "TARGET_ARCH64 || TARGET_V8PLUS"
3866 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
3871 (define_insn "*muldi3_sp64"
3872 [(set (match_operand:DI 0 "register_operand" "=r")
3873 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
3874 (match_operand:DI 2 "arith_operand" "rI")))]
3877 [(set_attr "type" "imul")])
3879 ;; V8plus wide multiply.
3881 (define_insn "muldi3_v8plus"
3882 [(set (match_operand:DI 0 "register_operand" "=r,h")
3883 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
3884 (match_operand:DI 2 "arith_operand" "rI,rI")))
3885 (clobber (match_scratch:SI 3 "=&h,X"))
3886 (clobber (match_scratch:SI 4 "=&h,X"))]
3889 if (sparc_check_64 (operands[1], insn) <= 0)
3890 output_asm_insn ("srl\t%L1, 0, %L1", operands);
3891 if (which_alternative == 1)
3892 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
3893 if (GET_CODE (operands[2]) == CONST_INT)
3895 if (which_alternative == 1)
3896 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
3898 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";
3900 else if (rtx_equal_p (operands[1], operands[2]))
3902 if (which_alternative == 1)
3903 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
3905 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";
3907 if (sparc_check_64 (operands[2], insn) <= 0)
3908 output_asm_insn ("srl\t%L2, 0, %L2", operands);
3909 if (which_alternative == 1)
3910 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";
3912 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";
3914 [(set_attr "type" "multi")
3915 (set_attr "length" "9,8")])
3917 (define_insn "*cmp_mul_set"
3919 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3920 (match_operand:SI 2 "arith_operand" "rI"))
3922 (set (match_operand:SI 0 "register_operand" "=r")
3923 (mult:SI (match_dup 1) (match_dup 2)))]
3924 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
3925 "smulcc\t%1, %2, %0"
3926 [(set_attr "type" "imul")])
3928 (define_expand "mulsidi3"
3929 [(set (match_operand:DI 0 "register_operand" "")
3930 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
3931 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
3934 if (CONSTANT_P (operands[2]))
3937 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
3939 else if (TARGET_ARCH32)
3940 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
3943 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
3949 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
3954 ;; V9 puts the 64-bit product in a 64-bit register. Only out or global
3955 ;; registers can hold 64-bit values in the V8plus environment.
3957 (define_insn "mulsidi3_v8plus"
3958 [(set (match_operand:DI 0 "register_operand" "=h,r")
3959 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
3960 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
3961 (clobber (match_scratch:SI 3 "=X,&h"))]
3964 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
3965 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
3966 [(set_attr "type" "multi")
3967 (set_attr "length" "2,3")])
3970 (define_insn "const_mulsidi3_v8plus"
3971 [(set (match_operand:DI 0 "register_operand" "=h,r")
3972 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
3973 (match_operand:DI 2 "small_int_operand" "I,I")))
3974 (clobber (match_scratch:SI 3 "=X,&h"))]
3977 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
3978 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
3979 [(set_attr "type" "multi")
3980 (set_attr "length" "2,3")])
3983 (define_insn "*mulsidi3_sp32"
3984 [(set (match_operand:DI 0 "register_operand" "=r")
3985 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3986 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
3989 return TARGET_SPARCLET
3990 ? "smuld\t%1, %2, %L0"
3991 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
3994 (if_then_else (eq_attr "isa" "sparclet")
3995 (const_string "imul") (const_string "multi")))
3996 (set (attr "length")
3997 (if_then_else (eq_attr "isa" "sparclet")
3998 (const_int 1) (const_int 2)))])
4000 (define_insn "*mulsidi3_sp64"
4001 [(set (match_operand:DI 0 "register_operand" "=r")
4002 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4003 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4004 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4006 [(set_attr "type" "imul")])
4008 ;; Extra pattern, because sign_extend of a constant isn't valid.
4011 (define_insn "const_mulsidi3_sp32"
4012 [(set (match_operand:DI 0 "register_operand" "=r")
4013 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4014 (match_operand:DI 2 "small_int_operand" "I")))]
4017 return TARGET_SPARCLET
4018 ? "smuld\t%1, %2, %L0"
4019 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4022 (if_then_else (eq_attr "isa" "sparclet")
4023 (const_string "imul") (const_string "multi")))
4024 (set (attr "length")
4025 (if_then_else (eq_attr "isa" "sparclet")
4026 (const_int 1) (const_int 2)))])
4028 (define_insn "const_mulsidi3_sp64"
4029 [(set (match_operand:DI 0 "register_operand" "=r")
4030 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4031 (match_operand:DI 2 "small_int_operand" "I")))]
4032 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4034 [(set_attr "type" "imul")])
4036 (define_expand "smulsi3_highpart"
4037 [(set (match_operand:SI 0 "register_operand" "")
4039 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4040 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4042 "TARGET_HARD_MUL && TARGET_ARCH32"
4044 if (CONSTANT_P (operands[2]))
4048 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4054 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4059 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4060 operands[2], GEN_INT (32)));
4066 (define_insn "smulsi3_highpart_v8plus"
4067 [(set (match_operand:SI 0 "register_operand" "=h,r")
4069 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4070 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4071 (match_operand:SI 3 "small_int_operand" "I,I"))))
4072 (clobber (match_scratch:SI 4 "=X,&h"))]
4075 smul\t%1, %2, %0\;srlx\t%0, %3, %0
4076 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4077 [(set_attr "type" "multi")
4078 (set_attr "length" "2")])
4080 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4083 [(set (match_operand:SI 0 "register_operand" "=h,r")
4086 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4087 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4088 (match_operand:SI 3 "small_int_operand" "I,I"))
4090 (clobber (match_scratch:SI 4 "=X,&h"))]
4093 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4094 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4095 [(set_attr "type" "multi")
4096 (set_attr "length" "2")])
4099 (define_insn "const_smulsi3_highpart_v8plus"
4100 [(set (match_operand:SI 0 "register_operand" "=h,r")
4102 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4103 (match_operand:DI 2 "small_int_operand" "I,I"))
4104 (match_operand:SI 3 "small_int_operand" "I,I"))))
4105 (clobber (match_scratch:SI 4 "=X,&h"))]
4108 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4109 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4110 [(set_attr "type" "multi")
4111 (set_attr "length" "2")])
4114 (define_insn "*smulsi3_highpart_sp32"
4115 [(set (match_operand:SI 0 "register_operand" "=r")
4117 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4118 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4121 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4122 [(set_attr "type" "multi")
4123 (set_attr "length" "2")])
4126 (define_insn "const_smulsi3_highpart"
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 (match_operand:DI 2 "small_int_operand" "i"))
4133 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4134 [(set_attr "type" "multi")
4135 (set_attr "length" "2")])
4137 (define_expand "umulsidi3"
4138 [(set (match_operand:DI 0 "register_operand" "")
4139 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4140 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4143 if (CONSTANT_P (operands[2]))
4146 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4148 else if (TARGET_ARCH32)
4149 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4152 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4158 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4164 (define_insn "umulsidi3_v8plus"
4165 [(set (match_operand:DI 0 "register_operand" "=h,r")
4166 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4167 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4168 (clobber (match_scratch:SI 3 "=X,&h"))]
4171 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4172 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4173 [(set_attr "type" "multi")
4174 (set_attr "length" "2,3")])
4177 (define_insn "*umulsidi3_sp32"
4178 [(set (match_operand:DI 0 "register_operand" "=r")
4179 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4180 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4183 return TARGET_SPARCLET
4184 ? "umuld\t%1, %2, %L0"
4185 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4188 (if_then_else (eq_attr "isa" "sparclet")
4189 (const_string "imul") (const_string "multi")))
4190 (set (attr "length")
4191 (if_then_else (eq_attr "isa" "sparclet")
4192 (const_int 1) (const_int 2)))])
4194 (define_insn "*umulsidi3_sp64"
4195 [(set (match_operand:DI 0 "register_operand" "=r")
4196 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4197 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4198 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4200 [(set_attr "type" "imul")])
4202 ;; Extra pattern, because sign_extend of a constant isn't valid.
4205 (define_insn "const_umulsidi3_sp32"
4206 [(set (match_operand:DI 0 "register_operand" "=r")
4207 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4208 (match_operand:DI 2 "uns_small_int_operand" "")))]
4211 return TARGET_SPARCLET
4212 ? "umuld\t%1, %s2, %L0"
4213 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4216 (if_then_else (eq_attr "isa" "sparclet")
4217 (const_string "imul") (const_string "multi")))
4218 (set (attr "length")
4219 (if_then_else (eq_attr "isa" "sparclet")
4220 (const_int 1) (const_int 2)))])
4222 (define_insn "const_umulsidi3_sp64"
4223 [(set (match_operand:DI 0 "register_operand" "=r")
4224 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4225 (match_operand:DI 2 "uns_small_int_operand" "")))]
4226 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4228 [(set_attr "type" "imul")])
4231 (define_insn "const_umulsidi3_v8plus"
4232 [(set (match_operand:DI 0 "register_operand" "=h,r")
4233 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4234 (match_operand:DI 2 "uns_small_int_operand" "")))
4235 (clobber (match_scratch:SI 3 "=X,h"))]
4238 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4239 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4240 [(set_attr "type" "multi")
4241 (set_attr "length" "2,3")])
4243 (define_expand "umulsi3_highpart"
4244 [(set (match_operand:SI 0 "register_operand" "")
4246 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4247 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4249 "TARGET_HARD_MUL && TARGET_ARCH32"
4251 if (CONSTANT_P (operands[2]))
4255 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4261 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4266 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4267 operands[2], GEN_INT (32)));
4273 (define_insn "umulsi3_highpart_v8plus"
4274 [(set (match_operand:SI 0 "register_operand" "=h,r")
4276 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4277 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4278 (match_operand:SI 3 "small_int_operand" "I,I"))))
4279 (clobber (match_scratch:SI 4 "=X,h"))]
4282 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4283 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4284 [(set_attr "type" "multi")
4285 (set_attr "length" "2")])
4288 (define_insn "const_umulsi3_highpart_v8plus"
4289 [(set (match_operand:SI 0 "register_operand" "=h,r")
4291 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4292 (match_operand:DI 2 "uns_small_int_operand" ""))
4293 (match_operand:SI 3 "small_int_operand" "I,I"))))
4294 (clobber (match_scratch:SI 4 "=X,h"))]
4297 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4298 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4299 [(set_attr "type" "multi")
4300 (set_attr "length" "2")])
4303 (define_insn "*umulsi3_highpart_sp32"
4304 [(set (match_operand:SI 0 "register_operand" "=r")
4306 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4307 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4310 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4311 [(set_attr "type" "multi")
4312 (set_attr "length" "2")])
4315 (define_insn "const_umulsi3_highpart"
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 (match_operand:DI 2 "uns_small_int_operand" ""))
4322 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4323 [(set_attr "type" "multi")
4324 (set_attr "length" "2")])
4326 (define_expand "divsi3"
4327 [(parallel [(set (match_operand:SI 0 "register_operand" "")
4328 (div:SI (match_operand:SI 1 "register_operand" "")
4329 (match_operand:SI 2 "input_operand" "")))
4330 (clobber (match_scratch:SI 3 ""))])]
4331 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4335 operands[3] = gen_reg_rtx(SImode);
4336 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4337 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4343 ;; The V8 architecture specifies that there must be at least 3 instructions
4344 ;; between a write to the Y register and a use of it for correct results.
4345 ;; We try to fill one of them with a simple constant or a memory load.
4347 (define_insn "divsi3_sp32"
4348 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4349 (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4350 (match_operand:SI 2 "input_operand" "rI,K,m")))
4351 (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4352 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4354 output_asm_insn ("sra\t%1, 31, %3", operands);
4355 output_asm_insn ("wr\t%3, 0, %%y", operands);
4357 switch (which_alternative)
4361 return "sdiv\t%1, %2, %0";
4363 return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4366 return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4368 return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4371 return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4373 return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4378 [(set_attr "type" "multi")
4379 (set (attr "length")
4380 (if_then_else (eq_attr "isa" "v9")
4381 (const_int 4) (const_int 6)))])
4383 (define_insn "divsi3_sp64"
4384 [(set (match_operand:SI 0 "register_operand" "=r")
4385 (div:SI (match_operand:SI 1 "register_operand" "r")
4386 (match_operand:SI 2 "input_operand" "rI")))
4387 (use (match_operand:SI 3 "register_operand" "r"))]
4388 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4389 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4390 [(set_attr "type" "multi")
4391 (set_attr "length" "2")])
4393 (define_insn "divdi3"
4394 [(set (match_operand:DI 0 "register_operand" "=r")
4395 (div:DI (match_operand:DI 1 "register_operand" "r")
4396 (match_operand:DI 2 "arith_operand" "rI")))]
4399 [(set_attr "type" "idiv")])
4401 (define_insn "*cmp_sdiv_cc_set"
4403 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4404 (match_operand:SI 2 "arith_operand" "rI"))
4406 (set (match_operand:SI 0 "register_operand" "=r")
4407 (div:SI (match_dup 1) (match_dup 2)))
4408 (clobber (match_scratch:SI 3 "=&r"))]
4409 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4411 output_asm_insn ("sra\t%1, 31, %3", operands);
4412 output_asm_insn ("wr\t%3, 0, %%y", operands);
4415 return "sdivcc\t%1, %2, %0";
4417 return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4419 [(set_attr "type" "multi")
4420 (set (attr "length")
4421 (if_then_else (eq_attr "isa" "v9")
4422 (const_int 3) (const_int 6)))])
4425 (define_expand "udivsi3"
4426 [(set (match_operand:SI 0 "register_operand" "")
4427 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4428 (match_operand:SI 2 "input_operand" "")))]
4429 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4432 ;; The V8 architecture specifies that there must be at least 3 instructions
4433 ;; between a write to the Y register and a use of it for correct results.
4434 ;; We try to fill one of them with a simple constant or a memory load.
4436 (define_insn "udivsi3_sp32"
4437 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
4438 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
4439 (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
4440 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4442 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4444 switch (which_alternative)
4448 return "udiv\t%1, %2, %0";
4450 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
4453 return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
4455 return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4458 return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
4460 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4463 return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
4465 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
4470 [(set_attr "type" "multi")
4471 (set (attr "length")
4472 (if_then_else (eq_attr "isa" "v9")
4473 (const_int 3) (const_int 5)))])
4475 (define_insn "udivsi3_sp64"
4476 [(set (match_operand:SI 0 "register_operand" "=r")
4477 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
4478 (match_operand:SI 2 "input_operand" "rI")))]
4479 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4480 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
4481 [(set_attr "type" "multi")
4482 (set_attr "length" "2")])
4484 (define_insn "udivdi3"
4485 [(set (match_operand:DI 0 "register_operand" "=r")
4486 (udiv:DI (match_operand:DI 1 "register_operand" "r")
4487 (match_operand:DI 2 "arith_operand" "rI")))]
4490 [(set_attr "type" "idiv")])
4492 (define_insn "*cmp_udiv_cc_set"
4494 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
4495 (match_operand:SI 2 "arith_operand" "rI"))
4497 (set (match_operand:SI 0 "register_operand" "=r")
4498 (udiv:SI (match_dup 1) (match_dup 2)))]
4499 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4501 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4504 return "udivcc\t%1, %2, %0";
4506 return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
4508 [(set_attr "type" "multi")
4509 (set (attr "length")
4510 (if_then_else (eq_attr "isa" "v9")
4511 (const_int 2) (const_int 5)))])
4513 ; sparclet multiply/accumulate insns
4515 (define_insn "*smacsi"
4516 [(set (match_operand:SI 0 "register_operand" "=r")
4517 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
4518 (match_operand:SI 2 "arith_operand" "rI"))
4519 (match_operand:SI 3 "register_operand" "0")))]
4522 [(set_attr "type" "imul")])
4524 (define_insn "*smacdi"
4525 [(set (match_operand:DI 0 "register_operand" "=r")
4526 (plus:DI (mult:DI (sign_extend:DI
4527 (match_operand:SI 1 "register_operand" "%r"))
4529 (match_operand:SI 2 "register_operand" "r")))
4530 (match_operand:DI 3 "register_operand" "0")))]
4532 "smacd\t%1, %2, %L0"
4533 [(set_attr "type" "imul")])
4535 (define_insn "*umacdi"
4536 [(set (match_operand:DI 0 "register_operand" "=r")
4537 (plus:DI (mult:DI (zero_extend:DI
4538 (match_operand:SI 1 "register_operand" "%r"))
4540 (match_operand:SI 2 "register_operand" "r")))
4541 (match_operand:DI 3 "register_operand" "0")))]
4543 "umacd\t%1, %2, %L0"
4544 [(set_attr "type" "imul")])
4547 ;; Boolean instructions.
4549 ;; We define DImode `and' so with DImode `not' we can get
4550 ;; DImode `andn'. Other combinations are possible.
4552 (define_expand "and<V64I:mode>3"
4553 [(set (match_operand:V64I 0 "register_operand" "")
4554 (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
4555 (match_operand:V64I 2 "arith_double_operand" "")))]
4559 (define_insn "*and<V64I:mode>3_sp32"
4560 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4561 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4562 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4567 [(set_attr "type" "*,fga")
4568 (set_attr "length" "2,*")
4569 (set_attr "fptype" "*,double")])
4571 (define_insn "*and<V64I:mode>3_sp64"
4572 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4573 (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4574 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4579 [(set_attr "type" "*,fga")
4580 (set_attr "fptype" "*,double")])
4582 (define_insn "and<V32I:mode>3"
4583 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4584 (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4585 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4590 [(set_attr "type" "*,fga")
4591 (set_attr "fptype" "*,single")])
4594 [(set (match_operand:SI 0 "register_operand" "")
4595 (and:SI (match_operand:SI 1 "register_operand" "")
4596 (match_operand:SI 2 "const_compl_high_operand" "")))
4597 (clobber (match_operand:SI 3 "register_operand" ""))]
4599 [(set (match_dup 3) (match_dup 4))
4600 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
4602 operands[4] = GEN_INT (~INTVAL (operands[2]));
4605 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
4606 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4607 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4608 (match_operand:V64I 2 "register_operand" "r,b")))]
4612 fandnot1\t%1, %2, %0"
4613 "&& reload_completed
4614 && ((GET_CODE (operands[0]) == REG
4615 && REGNO (operands[0]) < 32)
4616 || (GET_CODE (operands[0]) == SUBREG
4617 && GET_CODE (SUBREG_REG (operands[0])) == REG
4618 && REGNO (SUBREG_REG (operands[0])) < 32))"
4619 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
4620 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
4621 "operands[3] = gen_highpart (SImode, operands[0]);
4622 operands[4] = gen_highpart (SImode, operands[1]);
4623 operands[5] = gen_highpart (SImode, operands[2]);
4624 operands[6] = gen_lowpart (SImode, operands[0]);
4625 operands[7] = gen_lowpart (SImode, operands[1]);
4626 operands[8] = gen_lowpart (SImode, operands[2]);"
4627 [(set_attr "type" "*,fga")
4628 (set_attr "length" "2,*")
4629 (set_attr "fptype" "*,double")])
4631 (define_insn "*and_not_<V64I:mode>_sp64"
4632 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4633 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4634 (match_operand:V64I 2 "register_operand" "r,b")))]
4638 fandnot1\t%1, %2, %0"
4639 [(set_attr "type" "*,fga")
4640 (set_attr "fptype" "*,double")])
4642 (define_insn "*and_not_<V32I:mode>"
4643 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4644 (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
4645 (match_operand:V32I 2 "register_operand" "r,d")))]
4649 fandnot1s\t%1, %2, %0"
4650 [(set_attr "type" "*,fga")
4651 (set_attr "fptype" "*,single")])
4653 (define_expand "ior<V64I:mode>3"
4654 [(set (match_operand:V64I 0 "register_operand" "")
4655 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
4656 (match_operand:V64I 2 "arith_double_operand" "")))]
4660 (define_insn "*ior<V64I:mode>3_sp32"
4661 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4662 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4663 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4668 [(set_attr "type" "*,fga")
4669 (set_attr "length" "2,*")
4670 (set_attr "fptype" "*,double")])
4672 (define_insn "*ior<V64I:mode>3_sp64"
4673 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4674 (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4675 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4680 [(set_attr "type" "*,fga")
4681 (set_attr "fptype" "*,double")])
4683 (define_insn "ior<V32I:mode>3"
4684 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4685 (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4686 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4691 [(set_attr "type" "*,fga")
4692 (set_attr "fptype" "*,single")])
4695 [(set (match_operand:SI 0 "register_operand" "")
4696 (ior:SI (match_operand:SI 1 "register_operand" "")
4697 (match_operand:SI 2 "const_compl_high_operand" "")))
4698 (clobber (match_operand:SI 3 "register_operand" ""))]
4700 [(set (match_dup 3) (match_dup 4))
4701 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4703 operands[4] = GEN_INT (~INTVAL (operands[2]));
4706 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
4707 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4708 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4709 (match_operand:V64I 2 "register_operand" "r,b")))]
4713 fornot1\t%1, %2, %0"
4714 "&& reload_completed
4715 && ((GET_CODE (operands[0]) == REG
4716 && REGNO (operands[0]) < 32)
4717 || (GET_CODE (operands[0]) == SUBREG
4718 && GET_CODE (SUBREG_REG (operands[0])) == REG
4719 && REGNO (SUBREG_REG (operands[0])) < 32))"
4720 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
4721 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
4722 "operands[3] = gen_highpart (SImode, operands[0]);
4723 operands[4] = gen_highpart (SImode, operands[1]);
4724 operands[5] = gen_highpart (SImode, operands[2]);
4725 operands[6] = gen_lowpart (SImode, operands[0]);
4726 operands[7] = gen_lowpart (SImode, operands[1]);
4727 operands[8] = gen_lowpart (SImode, operands[2]);"
4728 [(set_attr "type" "*,fga")
4729 (set_attr "length" "2,*")
4730 (set_attr "fptype" "*,double")])
4732 (define_insn "*or_not_<V64I:mode>_sp64"
4733 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4734 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4735 (match_operand:V64I 2 "register_operand" "r,b")))]
4739 fornot1\t%1, %2, %0"
4740 [(set_attr "type" "*,fga")
4741 (set_attr "fptype" "*,double")])
4743 (define_insn "*or_not_<V32I:mode>"
4744 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4745 (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
4746 (match_operand:V32I 2 "register_operand" "r,d")))]
4750 fornot1s\t%1, %2, %0"
4751 [(set_attr "type" "*,fga")
4752 (set_attr "fptype" "*,single")])
4754 (define_expand "xor<V64I:mode>3"
4755 [(set (match_operand:V64I 0 "register_operand" "")
4756 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
4757 (match_operand:V64I 2 "arith_double_operand" "")))]
4761 (define_insn "*xor<V64I:mode>3_sp32"
4762 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4763 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4764 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4769 [(set_attr "type" "*,fga")
4770 (set_attr "length" "2,*")
4771 (set_attr "fptype" "*,double")])
4773 (define_insn "*xor<V64I:mode>3_sp64"
4774 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4775 (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
4776 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4781 [(set_attr "type" "*,fga")
4782 (set_attr "fptype" "*,double")])
4784 (define_insn "xor<V32I:mode>3"
4785 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4786 (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
4787 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4792 [(set_attr "type" "*,fga")
4793 (set_attr "fptype" "*,single")])
4796 [(set (match_operand:SI 0 "register_operand" "")
4797 (xor:SI (match_operand:SI 1 "register_operand" "")
4798 (match_operand:SI 2 "const_compl_high_operand" "")))
4799 (clobber (match_operand:SI 3 "register_operand" ""))]
4801 [(set (match_dup 3) (match_dup 4))
4802 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4804 operands[4] = GEN_INT (~INTVAL (operands[2]));
4808 [(set (match_operand:SI 0 "register_operand" "")
4809 (not:SI (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) (xor:SI (match_dup 3) (match_dup 1)))]
4816 operands[4] = GEN_INT (~INTVAL (operands[2]));
4819 ;; Split DImode logical operations requiring two instructions.
4821 [(set (match_operand:V64I 0 "register_operand" "")
4822 (match_operator:V64I 1 "cc_arith_operator" ; AND, IOR, XOR
4823 [(match_operand:V64I 2 "register_operand" "")
4824 (match_operand:V64I 3 "arith_double_operand" "")]))]
4827 && ((GET_CODE (operands[0]) == REG
4828 && REGNO (operands[0]) < 32)
4829 || (GET_CODE (operands[0]) == SUBREG
4830 && GET_CODE (SUBREG_REG (operands[0])) == REG
4831 && REGNO (SUBREG_REG (operands[0])) < 32))"
4832 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
4833 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
4835 operands[4] = gen_highpart (SImode, operands[0]);
4836 operands[5] = gen_lowpart (SImode, operands[0]);
4837 operands[6] = gen_highpart (SImode, operands[2]);
4838 operands[7] = gen_lowpart (SImode, operands[2]);
4839 #if HOST_BITS_PER_WIDE_INT == 32
4840 if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
4842 if (INTVAL (operands[3]) < 0)
4843 operands[8] = constm1_rtx;
4845 operands[8] = const0_rtx;
4849 operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
4850 operands[9] = gen_lowpart (SImode, operands[3]);
4853 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
4854 ;; Combine now canonicalizes to the rightmost expression.
4855 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
4856 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4857 (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
4858 (match_operand:V64I 2 "register_operand" "r,b"))))]
4863 "&& reload_completed
4864 && ((GET_CODE (operands[0]) == REG
4865 && REGNO (operands[0]) < 32)
4866 || (GET_CODE (operands[0]) == SUBREG
4867 && GET_CODE (SUBREG_REG (operands[0])) == REG
4868 && REGNO (SUBREG_REG (operands[0])) < 32))"
4869 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
4870 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
4871 "operands[3] = gen_highpart (SImode, operands[0]);
4872 operands[4] = gen_highpart (SImode, operands[1]);
4873 operands[5] = gen_highpart (SImode, operands[2]);
4874 operands[6] = gen_lowpart (SImode, operands[0]);
4875 operands[7] = gen_lowpart (SImode, operands[1]);
4876 operands[8] = gen_lowpart (SImode, operands[2]);"
4877 [(set_attr "type" "*,fga")
4878 (set_attr "length" "2,*")
4879 (set_attr "fptype" "*,double")])
4881 (define_insn "*xor_not_<V64I:mode>_sp64"
4882 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4883 (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
4884 (match_operand:V64I 2 "arith_operand" "rI,b"))))]
4889 [(set_attr "type" "*,fga")
4890 (set_attr "fptype" "*,double")])
4892 (define_insn "*xor_not_<V32I:mode>"
4893 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4894 (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
4895 (match_operand:V32I 2 "arith_operand" "rI,d"))))]
4900 [(set_attr "type" "*,fga")
4901 (set_attr "fptype" "*,single")])
4903 ;; These correspond to the above in the case where we also (or only)
4904 ;; want to set the condition code.
4906 (define_insn "*cmp_cc_arith_op"
4909 (match_operator:SI 2 "cc_arith_operator"
4910 [(match_operand:SI 0 "arith_operand" "%r")
4911 (match_operand:SI 1 "arith_operand" "rI")])
4914 "%A2cc\t%0, %1, %%g0"
4915 [(set_attr "type" "compare")])
4917 (define_insn "*cmp_ccx_arith_op"
4920 (match_operator:DI 2 "cc_arith_operator"
4921 [(match_operand:DI 0 "arith_operand" "%r")
4922 (match_operand:DI 1 "arith_operand" "rI")])
4925 "%A2cc\t%0, %1, %%g0"
4926 [(set_attr "type" "compare")])
4928 (define_insn "*cmp_cc_arith_op_set"
4931 (match_operator:SI 3 "cc_arith_operator"
4932 [(match_operand:SI 1 "arith_operand" "%r")
4933 (match_operand:SI 2 "arith_operand" "rI")])
4935 (set (match_operand:SI 0 "register_operand" "=r")
4936 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
4937 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
4939 [(set_attr "type" "compare")])
4941 (define_insn "*cmp_ccx_arith_op_set"
4944 (match_operator:DI 3 "cc_arith_operator"
4945 [(match_operand:DI 1 "arith_operand" "%r")
4946 (match_operand:DI 2 "arith_operand" "rI")])
4948 (set (match_operand:DI 0 "register_operand" "=r")
4949 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
4950 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
4952 [(set_attr "type" "compare")])
4954 (define_insn "*cmp_cc_xor_not"
4957 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
4958 (match_operand:SI 1 "arith_operand" "rI")))
4961 "xnorcc\t%r0, %1, %%g0"
4962 [(set_attr "type" "compare")])
4964 (define_insn "*cmp_ccx_xor_not"
4967 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
4968 (match_operand:DI 1 "arith_operand" "rI")))
4971 "xnorcc\t%r0, %1, %%g0"
4972 [(set_attr "type" "compare")])
4974 (define_insn "*cmp_cc_xor_not_set"
4977 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4978 (match_operand:SI 2 "arith_operand" "rI")))
4980 (set (match_operand:SI 0 "register_operand" "=r")
4981 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
4983 "xnorcc\t%r1, %2, %0"
4984 [(set_attr "type" "compare")])
4986 (define_insn "*cmp_ccx_xor_not_set"
4989 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
4990 (match_operand:DI 2 "arith_operand" "rI")))
4992 (set (match_operand:DI 0 "register_operand" "=r")
4993 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
4995 "xnorcc\t%r1, %2, %0"
4996 [(set_attr "type" "compare")])
4998 (define_insn "*cmp_cc_arith_op_not"
5001 (match_operator:SI 2 "cc_arith_not_operator"
5002 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5003 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5006 "%B2cc\t%r1, %0, %%g0"
5007 [(set_attr "type" "compare")])
5009 (define_insn "*cmp_ccx_arith_op_not"
5012 (match_operator:DI 2 "cc_arith_not_operator"
5013 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5014 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5017 "%B2cc\t%r1, %0, %%g0"
5018 [(set_attr "type" "compare")])
5020 (define_insn "*cmp_cc_arith_op_not_set"
5023 (match_operator:SI 3 "cc_arith_not_operator"
5024 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5025 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5027 (set (match_operand:SI 0 "register_operand" "=r")
5028 (match_operator:SI 4 "cc_arith_not_operator"
5029 [(not:SI (match_dup 1)) (match_dup 2)]))]
5030 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5031 "%B3cc\t%r2, %1, %0"
5032 [(set_attr "type" "compare")])
5034 (define_insn "*cmp_ccx_arith_op_not_set"
5037 (match_operator:DI 3 "cc_arith_not_operator"
5038 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5039 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5041 (set (match_operand:DI 0 "register_operand" "=r")
5042 (match_operator:DI 4 "cc_arith_not_operator"
5043 [(not:DI (match_dup 1)) (match_dup 2)]))]
5044 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5045 "%B3cc\t%r2, %1, %0"
5046 [(set_attr "type" "compare")])
5048 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5049 ;; does not know how to make it work for constants.
5051 (define_expand "negdi2"
5052 [(set (match_operand:DI 0 "register_operand" "=r")
5053 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5056 if (! TARGET_ARCH64)
5058 emit_insn (gen_rtx_PARALLEL
5061 gen_rtx_SET (VOIDmode, operand0,
5062 gen_rtx_NEG (DImode, operand1)),
5063 gen_rtx_CLOBBER (VOIDmode,
5064 gen_rtx_REG (CCmode,
5070 (define_insn_and_split "*negdi2_sp32"
5071 [(set (match_operand:DI 0 "register_operand" "=r")
5072 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5073 (clobber (reg:CC 100))]
5076 "&& reload_completed"
5077 [(parallel [(set (reg:CC_NOOV 100)
5078 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5080 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5081 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5082 (ltu:SI (reg:CC 100) (const_int 0))))]
5083 "operands[2] = gen_highpart (SImode, operands[0]);
5084 operands[3] = gen_highpart (SImode, operands[1]);
5085 operands[4] = gen_lowpart (SImode, operands[0]);
5086 operands[5] = gen_lowpart (SImode, operands[1]);"
5087 [(set_attr "length" "2")])
5089 (define_insn "*negdi2_sp64"
5090 [(set (match_operand:DI 0 "register_operand" "=r")
5091 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5093 "sub\t%%g0, %1, %0")
5095 (define_insn "negsi2"
5096 [(set (match_operand:SI 0 "register_operand" "=r")
5097 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5099 "sub\t%%g0, %1, %0")
5101 (define_insn "*cmp_cc_neg"
5102 [(set (reg:CC_NOOV 100)
5103 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5106 "subcc\t%%g0, %0, %%g0"
5107 [(set_attr "type" "compare")])
5109 (define_insn "*cmp_ccx_neg"
5110 [(set (reg:CCX_NOOV 100)
5111 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5114 "subcc\t%%g0, %0, %%g0"
5115 [(set_attr "type" "compare")])
5117 (define_insn "*cmp_cc_set_neg"
5118 [(set (reg:CC_NOOV 100)
5119 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5121 (set (match_operand:SI 0 "register_operand" "=r")
5122 (neg:SI (match_dup 1)))]
5124 "subcc\t%%g0, %1, %0"
5125 [(set_attr "type" "compare")])
5127 (define_insn "*cmp_ccx_set_neg"
5128 [(set (reg:CCX_NOOV 100)
5129 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5131 (set (match_operand:DI 0 "register_operand" "=r")
5132 (neg:DI (match_dup 1)))]
5134 "subcc\t%%g0, %1, %0"
5135 [(set_attr "type" "compare")])
5137 ;; We cannot use the "not" pseudo insn because the Sun assembler
5138 ;; does not know how to make it work for constants.
5139 (define_expand "one_cmpl<V64I:mode>2"
5140 [(set (match_operand:V64I 0 "register_operand" "")
5141 (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5145 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5146 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5147 (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5152 "&& reload_completed
5153 && ((GET_CODE (operands[0]) == REG
5154 && REGNO (operands[0]) < 32)
5155 || (GET_CODE (operands[0]) == SUBREG
5156 && GET_CODE (SUBREG_REG (operands[0])) == REG
5157 && REGNO (SUBREG_REG (operands[0])) < 32))"
5158 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5159 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5160 "operands[2] = gen_highpart (SImode, operands[0]);
5161 operands[3] = gen_highpart (SImode, operands[1]);
5162 operands[4] = gen_lowpart (SImode, operands[0]);
5163 operands[5] = gen_lowpart (SImode, operands[1]);"
5164 [(set_attr "type" "*,fga")
5165 (set_attr "length" "2,*")
5166 (set_attr "fptype" "*,double")])
5168 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5169 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5170 (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5175 [(set_attr "type" "*,fga")
5176 (set_attr "fptype" "*,double")])
5178 (define_insn "one_cmpl<V32I:mode>2"
5179 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5180 (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5185 [(set_attr "type" "*,fga")
5186 (set_attr "fptype" "*,single")])
5188 (define_insn "*cmp_cc_not"
5190 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5193 "xnorcc\t%%g0, %0, %%g0"
5194 [(set_attr "type" "compare")])
5196 (define_insn "*cmp_ccx_not"
5198 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5201 "xnorcc\t%%g0, %0, %%g0"
5202 [(set_attr "type" "compare")])
5204 (define_insn "*cmp_cc_set_not"
5206 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5208 (set (match_operand:SI 0 "register_operand" "=r")
5209 (not:SI (match_dup 1)))]
5211 "xnorcc\t%%g0, %1, %0"
5212 [(set_attr "type" "compare")])
5214 (define_insn "*cmp_ccx_set_not"
5216 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5218 (set (match_operand:DI 0 "register_operand" "=r")
5219 (not:DI (match_dup 1)))]
5221 "xnorcc\t%%g0, %1, %0"
5222 [(set_attr "type" "compare")])
5224 (define_insn "*cmp_cc_set"
5225 [(set (match_operand:SI 0 "register_operand" "=r")
5226 (match_operand:SI 1 "register_operand" "r"))
5228 (compare:CC (match_dup 1)
5232 [(set_attr "type" "compare")])
5234 (define_insn "*cmp_ccx_set64"
5235 [(set (match_operand:DI 0 "register_operand" "=r")
5236 (match_operand:DI 1 "register_operand" "r"))
5238 (compare:CCX (match_dup 1)
5242 [(set_attr "type" "compare")])
5245 ;; Floating point arithmetic instructions.
5247 (define_expand "addtf3"
5248 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5249 (plus:TF (match_operand:TF 1 "general_operand" "")
5250 (match_operand:TF 2 "general_operand" "")))]
5251 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5252 "emit_tfmode_binop (PLUS, operands); DONE;")
5254 (define_insn "*addtf3_hq"
5255 [(set (match_operand:TF 0 "register_operand" "=e")
5256 (plus:TF (match_operand:TF 1 "register_operand" "e")
5257 (match_operand:TF 2 "register_operand" "e")))]
5258 "TARGET_FPU && TARGET_HARD_QUAD"
5260 [(set_attr "type" "fp")])
5262 (define_insn "adddf3"
5263 [(set (match_operand:DF 0 "register_operand" "=e")
5264 (plus:DF (match_operand:DF 1 "register_operand" "e")
5265 (match_operand:DF 2 "register_operand" "e")))]
5268 [(set_attr "type" "fp")
5269 (set_attr "fptype" "double")])
5271 (define_insn "addsf3"
5272 [(set (match_operand:SF 0 "register_operand" "=f")
5273 (plus:SF (match_operand:SF 1 "register_operand" "f")
5274 (match_operand:SF 2 "register_operand" "f")))]
5277 [(set_attr "type" "fp")])
5279 (define_expand "subtf3"
5280 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5281 (minus:TF (match_operand:TF 1 "general_operand" "")
5282 (match_operand:TF 2 "general_operand" "")))]
5283 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5284 "emit_tfmode_binop (MINUS, operands); DONE;")
5286 (define_insn "*subtf3_hq"
5287 [(set (match_operand:TF 0 "register_operand" "=e")
5288 (minus:TF (match_operand:TF 1 "register_operand" "e")
5289 (match_operand:TF 2 "register_operand" "e")))]
5290 "TARGET_FPU && TARGET_HARD_QUAD"
5292 [(set_attr "type" "fp")])
5294 (define_insn "subdf3"
5295 [(set (match_operand:DF 0 "register_operand" "=e")
5296 (minus:DF (match_operand:DF 1 "register_operand" "e")
5297 (match_operand:DF 2 "register_operand" "e")))]
5300 [(set_attr "type" "fp")
5301 (set_attr "fptype" "double")])
5303 (define_insn "subsf3"
5304 [(set (match_operand:SF 0 "register_operand" "=f")
5305 (minus:SF (match_operand:SF 1 "register_operand" "f")
5306 (match_operand:SF 2 "register_operand" "f")))]
5309 [(set_attr "type" "fp")])
5311 (define_expand "multf3"
5312 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5313 (mult:TF (match_operand:TF 1 "general_operand" "")
5314 (match_operand:TF 2 "general_operand" "")))]
5315 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5316 "emit_tfmode_binop (MULT, operands); DONE;")
5318 (define_insn "*multf3_hq"
5319 [(set (match_operand:TF 0 "register_operand" "=e")
5320 (mult:TF (match_operand:TF 1 "register_operand" "e")
5321 (match_operand:TF 2 "register_operand" "e")))]
5322 "TARGET_FPU && TARGET_HARD_QUAD"
5324 [(set_attr "type" "fpmul")])
5326 (define_insn "muldf3"
5327 [(set (match_operand:DF 0 "register_operand" "=e")
5328 (mult:DF (match_operand:DF 1 "register_operand" "e")
5329 (match_operand:DF 2 "register_operand" "e")))]
5332 [(set_attr "type" "fpmul")
5333 (set_attr "fptype" "double")])
5335 (define_insn "mulsf3"
5336 [(set (match_operand:SF 0 "register_operand" "=f")
5337 (mult:SF (match_operand:SF 1 "register_operand" "f")
5338 (match_operand:SF 2 "register_operand" "f")))]
5341 [(set_attr "type" "fpmul")])
5343 (define_insn "*muldf3_extend"
5344 [(set (match_operand:DF 0 "register_operand" "=e")
5345 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5346 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5347 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
5348 "fsmuld\t%1, %2, %0"
5349 [(set_attr "type" "fpmul")
5350 (set_attr "fptype" "double")])
5352 (define_insn "*multf3_extend"
5353 [(set (match_operand:TF 0 "register_operand" "=e")
5354 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5355 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5356 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5357 "fdmulq\t%1, %2, %0"
5358 [(set_attr "type" "fpmul")])
5360 (define_expand "divtf3"
5361 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5362 (div:TF (match_operand:TF 1 "general_operand" "")
5363 (match_operand:TF 2 "general_operand" "")))]
5364 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5365 "emit_tfmode_binop (DIV, operands); DONE;")
5367 ;; don't have timing for quad-prec. divide.
5368 (define_insn "*divtf3_hq"
5369 [(set (match_operand:TF 0 "register_operand" "=e")
5370 (div:TF (match_operand:TF 1 "register_operand" "e")
5371 (match_operand:TF 2 "register_operand" "e")))]
5372 "TARGET_FPU && TARGET_HARD_QUAD"
5374 [(set_attr "type" "fpdivd")])
5376 (define_insn "divdf3"
5377 [(set (match_operand:DF 0 "register_operand" "=e")
5378 (div:DF (match_operand:DF 1 "register_operand" "e")
5379 (match_operand:DF 2 "register_operand" "e")))]
5382 [(set_attr "type" "fpdivd")
5383 (set_attr "fptype" "double")])
5385 (define_insn "divsf3"
5386 [(set (match_operand:SF 0 "register_operand" "=f")
5387 (div:SF (match_operand:SF 1 "register_operand" "f")
5388 (match_operand:SF 2 "register_operand" "f")))]
5391 [(set_attr "type" "fpdivs")])
5393 (define_expand "negtf2"
5394 [(set (match_operand:TF 0 "register_operand" "=e,e")
5395 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5399 (define_insn_and_split "*negtf2_notv9"
5400 [(set (match_operand:TF 0 "register_operand" "=e,e")
5401 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5402 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5408 "&& reload_completed
5409 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5410 [(set (match_dup 2) (neg:SF (match_dup 3)))
5411 (set (match_dup 4) (match_dup 5))
5412 (set (match_dup 6) (match_dup 7))]
5413 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5414 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5415 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5416 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5417 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5418 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5419 [(set_attr "type" "fpmove,*")
5420 (set_attr "length" "*,2")])
5422 (define_insn_and_split "*negtf2_v9"
5423 [(set (match_operand:TF 0 "register_operand" "=e,e")
5424 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5425 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5426 "TARGET_FPU && TARGET_V9"
5430 "&& reload_completed
5431 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5432 [(set (match_dup 2) (neg:DF (match_dup 3)))
5433 (set (match_dup 4) (match_dup 5))]
5434 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5435 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5436 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5437 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5438 [(set_attr "type" "fpmove,*")
5439 (set_attr "length" "*,2")
5440 (set_attr "fptype" "double")])
5442 (define_expand "negdf2"
5443 [(set (match_operand:DF 0 "register_operand" "")
5444 (neg:DF (match_operand:DF 1 "register_operand" "")))]
5448 (define_insn_and_split "*negdf2_notv9"
5449 [(set (match_operand:DF 0 "register_operand" "=e,e")
5450 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
5451 "TARGET_FPU && ! TARGET_V9"
5455 "&& reload_completed
5456 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5457 [(set (match_dup 2) (neg:SF (match_dup 3)))
5458 (set (match_dup 4) (match_dup 5))]
5459 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5460 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5461 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5462 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5463 [(set_attr "type" "fpmove,*")
5464 (set_attr "length" "*,2")])
5466 (define_insn "*negdf2_v9"
5467 [(set (match_operand:DF 0 "register_operand" "=e")
5468 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5469 "TARGET_FPU && TARGET_V9"
5471 [(set_attr "type" "fpmove")
5472 (set_attr "fptype" "double")])
5474 (define_insn "negsf2"
5475 [(set (match_operand:SF 0 "register_operand" "=f")
5476 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
5479 [(set_attr "type" "fpmove")])
5481 (define_expand "abstf2"
5482 [(set (match_operand:TF 0 "register_operand" "")
5483 (abs:TF (match_operand:TF 1 "register_operand" "")))]
5487 (define_insn_and_split "*abstf2_notv9"
5488 [(set (match_operand:TF 0 "register_operand" "=e,e")
5489 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5490 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5491 "TARGET_FPU && ! TARGET_V9"
5495 "&& reload_completed
5496 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5497 [(set (match_dup 2) (abs:SF (match_dup 3)))
5498 (set (match_dup 4) (match_dup 5))
5499 (set (match_dup 6) (match_dup 7))]
5500 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5501 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5502 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5503 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5504 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5505 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5506 [(set_attr "type" "fpmove,*")
5507 (set_attr "length" "*,2")])
5509 (define_insn "*abstf2_hq_v9"
5510 [(set (match_operand:TF 0 "register_operand" "=e,e")
5511 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5512 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
5516 [(set_attr "type" "fpmove")
5517 (set_attr "fptype" "double,*")])
5519 (define_insn_and_split "*abstf2_v9"
5520 [(set (match_operand:TF 0 "register_operand" "=e,e")
5521 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5522 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
5526 "&& reload_completed
5527 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5528 [(set (match_dup 2) (abs:DF (match_dup 3)))
5529 (set (match_dup 4) (match_dup 5))]
5530 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5531 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5532 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5533 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5534 [(set_attr "type" "fpmove,*")
5535 (set_attr "length" "*,2")
5536 (set_attr "fptype" "double,*")])
5538 (define_expand "absdf2"
5539 [(set (match_operand:DF 0 "register_operand" "")
5540 (abs:DF (match_operand:DF 1 "register_operand" "")))]
5544 (define_insn_and_split "*absdf2_notv9"
5545 [(set (match_operand:DF 0 "register_operand" "=e,e")
5546 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
5547 "TARGET_FPU && ! TARGET_V9"
5551 "&& reload_completed
5552 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5553 [(set (match_dup 2) (abs:SF (match_dup 3)))
5554 (set (match_dup 4) (match_dup 5))]
5555 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5556 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5557 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5558 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5559 [(set_attr "type" "fpmove,*")
5560 (set_attr "length" "*,2")])
5562 (define_insn "*absdf2_v9"
5563 [(set (match_operand:DF 0 "register_operand" "=e")
5564 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5565 "TARGET_FPU && TARGET_V9"
5567 [(set_attr "type" "fpmove")
5568 (set_attr "fptype" "double")])
5570 (define_insn "abssf2"
5571 [(set (match_operand:SF 0 "register_operand" "=f")
5572 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
5575 [(set_attr "type" "fpmove")])
5577 (define_expand "sqrttf2"
5578 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5579 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
5580 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5581 "emit_tfmode_unop (SQRT, operands); DONE;")
5583 (define_insn "*sqrttf2_hq"
5584 [(set (match_operand:TF 0 "register_operand" "=e")
5585 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
5586 "TARGET_FPU && TARGET_HARD_QUAD"
5588 [(set_attr "type" "fpsqrtd")])
5590 (define_insn "sqrtdf2"
5591 [(set (match_operand:DF 0 "register_operand" "=e")
5592 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5595 [(set_attr "type" "fpsqrtd")
5596 (set_attr "fptype" "double")])
5598 (define_insn "sqrtsf2"
5599 [(set (match_operand:SF 0 "register_operand" "=f")
5600 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
5603 [(set_attr "type" "fpsqrts")])
5606 ;; Arithmetic shift instructions.
5608 (define_insn "ashlsi3"
5609 [(set (match_operand:SI 0 "register_operand" "=r")
5610 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5611 (match_operand:SI 2 "arith_operand" "rI")))]
5614 if (GET_CODE (operands[2]) == CONST_INT)
5615 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5616 return "sll\t%1, %2, %0";
5619 (if_then_else (match_operand 2 "const_one_operand" "")
5620 (const_string "ialu") (const_string "shift")))])
5622 (define_expand "ashldi3"
5623 [(set (match_operand:DI 0 "register_operand" "=r")
5624 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5625 (match_operand:SI 2 "arith_operand" "rI")))]
5626 "TARGET_ARCH64 || TARGET_V8PLUS"
5628 if (! TARGET_ARCH64)
5630 if (GET_CODE (operands[2]) == CONST_INT)
5632 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
5637 (define_insn "*ashldi3_sp64"
5638 [(set (match_operand:DI 0 "register_operand" "=r")
5639 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5640 (match_operand:SI 2 "arith_operand" "rI")))]
5643 if (GET_CODE (operands[2]) == CONST_INT)
5644 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5645 return "sllx\t%1, %2, %0";
5648 (if_then_else (match_operand 2 "const_one_operand" "")
5649 (const_string "ialu") (const_string "shift")))])
5652 (define_insn "ashldi3_v8plus"
5653 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5654 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5655 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5656 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5658 "* return output_v8plus_shift (operands, insn, \"sllx\");"
5659 [(set_attr "type" "multi")
5660 (set_attr "length" "5,5,6")])
5662 ;; Optimize (1LL<<x)-1
5663 ;; XXX this also needs to be fixed to handle equal subregs
5664 ;; XXX first before we could re-enable it.
5666 ; [(set (match_operand:DI 0 "register_operand" "=h")
5667 ; (plus:DI (ashift:DI (const_int 1)
5668 ; (match_operand:SI 1 "arith_operand" "rI"))
5670 ; "0 && TARGET_V8PLUS"
5672 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
5673 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5674 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5676 ; [(set_attr "type" "multi")
5677 ; (set_attr "length" "4")])
5679 (define_insn "*cmp_cc_ashift_1"
5680 [(set (reg:CC_NOOV 100)
5681 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
5685 "addcc\t%0, %0, %%g0"
5686 [(set_attr "type" "compare")])
5688 (define_insn "*cmp_cc_set_ashift_1"
5689 [(set (reg:CC_NOOV 100)
5690 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
5693 (set (match_operand:SI 0 "register_operand" "=r")
5694 (ashift:SI (match_dup 1) (const_int 1)))]
5697 [(set_attr "type" "compare")])
5699 (define_insn "ashrsi3"
5700 [(set (match_operand:SI 0 "register_operand" "=r")
5701 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5702 (match_operand:SI 2 "arith_operand" "rI")))]
5705 if (GET_CODE (operands[2]) == CONST_INT)
5706 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5707 return "sra\t%1, %2, %0";
5709 [(set_attr "type" "shift")])
5711 (define_insn "*ashrsi3_extend"
5712 [(set (match_operand:DI 0 "register_operand" "=r")
5713 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5714 (match_operand:SI 2 "arith_operand" "r"))))]
5717 [(set_attr "type" "shift")])
5719 ;; This handles the case as above, but with constant shift instead of
5720 ;; register. Combiner "simplifies" it for us a little bit though.
5721 (define_insn "*ashrsi3_extend2"
5722 [(set (match_operand:DI 0 "register_operand" "=r")
5723 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5725 (match_operand:SI 2 "small_int_operand" "I")))]
5726 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
5728 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5729 return "sra\t%1, %2, %0";
5731 [(set_attr "type" "shift")])
5733 (define_expand "ashrdi3"
5734 [(set (match_operand:DI 0 "register_operand" "=r")
5735 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5736 (match_operand:SI 2 "arith_operand" "rI")))]
5737 "TARGET_ARCH64 || TARGET_V8PLUS"
5739 if (! TARGET_ARCH64)
5741 if (GET_CODE (operands[2]) == CONST_INT)
5742 FAIL; /* prefer generic code in this case */
5743 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
5748 (define_insn "*ashrdi3_sp64"
5749 [(set (match_operand:DI 0 "register_operand" "=r")
5750 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5751 (match_operand:SI 2 "arith_operand" "rI")))]
5755 if (GET_CODE (operands[2]) == CONST_INT)
5756 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5757 return "srax\t%1, %2, %0";
5759 [(set_attr "type" "shift")])
5762 (define_insn "ashrdi3_v8plus"
5763 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5764 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5765 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5766 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5768 "* return output_v8plus_shift (operands, insn, \"srax\");"
5769 [(set_attr "type" "multi")
5770 (set_attr "length" "5,5,6")])
5772 (define_insn "lshrsi3"
5773 [(set (match_operand:SI 0 "register_operand" "=r")
5774 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5775 (match_operand:SI 2 "arith_operand" "rI")))]
5778 if (GET_CODE (operands[2]) == CONST_INT)
5779 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5780 return "srl\t%1, %2, %0";
5782 [(set_attr "type" "shift")])
5784 ;; This handles the case where
5785 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
5786 ;; but combiner "simplifies" it for us.
5787 (define_insn "*lshrsi3_extend"
5788 [(set (match_operand:DI 0 "register_operand" "=r")
5789 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5790 (match_operand:SI 2 "arith_operand" "r")) 0)
5791 (match_operand 3 "const_int_operand" "")))]
5792 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
5794 [(set_attr "type" "shift")])
5796 ;; This handles the case where
5797 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
5798 ;; but combiner "simplifies" it for us.
5799 (define_insn "*lshrsi3_extend2"
5800 [(set (match_operand:DI 0 "register_operand" "=r")
5801 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5802 (match_operand 2 "small_int_operand" "I")
5804 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5806 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
5807 return "srl\t%1, %2, %0";
5809 [(set_attr "type" "shift")])
5811 (define_expand "lshrdi3"
5812 [(set (match_operand:DI 0 "register_operand" "=r")
5813 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5814 (match_operand:SI 2 "arith_operand" "rI")))]
5815 "TARGET_ARCH64 || TARGET_V8PLUS"
5817 if (! TARGET_ARCH64)
5819 if (GET_CODE (operands[2]) == CONST_INT)
5821 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
5826 (define_insn "*lshrdi3_sp64"
5827 [(set (match_operand:DI 0 "register_operand" "=r")
5828 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5829 (match_operand:SI 2 "arith_operand" "rI")))]
5832 if (GET_CODE (operands[2]) == CONST_INT)
5833 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5834 return "srlx\t%1, %2, %0";
5836 [(set_attr "type" "shift")])
5839 (define_insn "lshrdi3_v8plus"
5840 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5841 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5842 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5843 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5845 "* return output_v8plus_shift (operands, insn, \"srlx\");"
5846 [(set_attr "type" "multi")
5847 (set_attr "length" "5,5,6")])
5850 [(set (match_operand:SI 0 "register_operand" "=r")
5851 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5853 (match_operand:SI 2 "small_int_operand" "I")))]
5854 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5856 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
5857 return "srax\t%1, %2, %0";
5859 [(set_attr "type" "shift")])
5862 [(set (match_operand:SI 0 "register_operand" "=r")
5863 (lshiftrt:SI (subreg:SI (ashiftrt: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 "srlx\t%1, %2, %0";
5871 [(set_attr "type" "shift")])
5874 [(set (match_operand:SI 0 "register_operand" "=r")
5875 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5876 (match_operand:SI 2 "small_int_operand" "I")) 4)
5877 (match_operand:SI 3 "small_int_operand" "I")))]
5879 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
5880 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
5881 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
5883 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
5885 return "srax\t%1, %2, %0";
5887 [(set_attr "type" "shift")])
5890 [(set (match_operand:SI 0 "register_operand" "=r")
5891 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5892 (match_operand:SI 2 "small_int_operand" "I")) 4)
5893 (match_operand:SI 3 "small_int_operand" "I")))]
5895 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
5896 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
5897 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
5899 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
5901 return "srlx\t%1, %2, %0";
5903 [(set_attr "type" "shift")])
5906 ;; Unconditional and other jump instructions.
5909 [(set (pc) (label_ref (match_operand 0 "" "")))]
5911 "* return output_ubranch (operands[0], 0, insn);"
5912 [(set_attr "type" "uncond_branch")])
5914 (define_expand "tablejump"
5915 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
5916 (use (label_ref (match_operand 1 "" "")))])]
5919 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
5921 /* In pic mode, our address differences are against the base of the
5922 table. Add that base value back in; CSE ought to be able to combine
5923 the two address loads. */
5927 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
5929 if (CASE_VECTOR_MODE != Pmode)
5930 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
5931 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
5932 operands[0] = memory_address (Pmode, tmp);
5936 (define_insn "*tablejump_sp32"
5937 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
5938 (use (label_ref (match_operand 1 "" "")))]
5941 [(set_attr "type" "uncond_branch")])
5943 (define_insn "*tablejump_sp64"
5944 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
5945 (use (label_ref (match_operand 1 "" "")))]
5948 [(set_attr "type" "uncond_branch")])
5951 ;; Jump to subroutine instructions.
5953 (define_expand "call"
5954 ;; Note that this expression is not used for generating RTL.
5955 ;; All the RTL is generated explicitly below.
5956 [(call (match_operand 0 "call_operand" "")
5957 (match_operand 3 "" "i"))]
5958 ;; operands[2] is next_arg_register
5959 ;; operands[3] is struct_value_size_rtx.
5964 gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
5966 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
5968 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
5970 /* This is really a PIC sequence. We want to represent
5971 it as a funny jump so its delay slots can be filled.
5973 ??? But if this really *is* a CALL, will not it clobber the
5974 call-clobbered registers? We lose this if it is a JUMP_INSN.
5975 Why cannot we have delay slots filled if it were a CALL? */
5977 /* We accept negative sizes for untyped calls. */
5978 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
5983 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
5985 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
5991 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
5992 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
5996 fn_rtx = operands[0];
5998 /* We accept negative sizes for untyped calls. */
5999 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6000 sparc_emit_call_insn
6003 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6005 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6008 sparc_emit_call_insn
6011 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6012 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6020 ;; We can't use the same pattern for these two insns, because then registers
6021 ;; in the address may not be properly reloaded.
6023 (define_insn "*call_address_sp32"
6024 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6025 (match_operand 1 "" ""))
6026 (clobber (reg:SI 15))]
6027 ;;- Do not use operand 1 for most machines.
6030 [(set_attr "type" "call")])
6032 (define_insn "*call_symbolic_sp32"
6033 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6034 (match_operand 1 "" ""))
6035 (clobber (reg:SI 15))]
6036 ;;- Do not use operand 1 for most machines.
6039 [(set_attr "type" "call")])
6041 (define_insn "*call_address_sp64"
6042 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6043 (match_operand 1 "" ""))
6044 (clobber (reg:DI 15))]
6045 ;;- Do not use operand 1 for most machines.
6048 [(set_attr "type" "call")])
6050 (define_insn "*call_symbolic_sp64"
6051 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6052 (match_operand 1 "" ""))
6053 (clobber (reg:DI 15))]
6054 ;;- Do not use operand 1 for most machines.
6057 [(set_attr "type" "call")])
6059 ;; This is a call that wants a structure value.
6060 ;; There is no such critter for v9 (??? we may need one anyway).
6061 (define_insn "*call_address_struct_value_sp32"
6062 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6063 (match_operand 1 "" ""))
6064 (match_operand 2 "immediate_operand" "")
6065 (clobber (reg:SI 15))]
6066 ;;- Do not use operand 1 for most machines.
6067 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6069 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6070 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6072 [(set_attr "type" "call_no_delay_slot")
6073 (set_attr "length" "3")])
6075 ;; This is a call that wants a structure value.
6076 ;; There is no such critter for v9 (??? we may need one anyway).
6077 (define_insn "*call_symbolic_struct_value_sp32"
6078 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6079 (match_operand 1 "" ""))
6080 (match_operand 2 "immediate_operand" "")
6081 (clobber (reg:SI 15))]
6082 ;;- Do not use operand 1 for most machines.
6083 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6085 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6086 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6088 [(set_attr "type" "call_no_delay_slot")
6089 (set_attr "length" "3")])
6091 ;; This is a call that may want a structure value. This is used for
6093 (define_insn "*call_address_untyped_struct_value_sp32"
6094 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6095 (match_operand 1 "" ""))
6096 (match_operand 2 "immediate_operand" "")
6097 (clobber (reg:SI 15))]
6098 ;;- Do not use operand 1 for most machines.
6099 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6100 "call\t%a0, %1\n\t nop\n\tnop"
6101 [(set_attr "type" "call_no_delay_slot")
6102 (set_attr "length" "3")])
6104 ;; This is a call that may want a structure value. This is used for
6106 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6107 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6108 (match_operand 1 "" ""))
6109 (match_operand 2 "immediate_operand" "")
6110 (clobber (reg:SI 15))]
6111 ;;- Do not use operand 1 for most machines.
6112 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6113 "call\t%a0, %1\n\t nop\n\tnop"
6114 [(set_attr "type" "call_no_delay_slot")
6115 (set_attr "length" "3")])
6117 (define_expand "call_value"
6118 ;; Note that this expression is not used for generating RTL.
6119 ;; All the RTL is generated explicitly below.
6120 [(set (match_operand 0 "register_operand" "=rf")
6121 (call (match_operand 1 "" "")
6122 (match_operand 4 "" "")))]
6123 ;; operand 2 is stack_size_rtx
6124 ;; operand 3 is next_arg_register
6130 gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6132 fn_rtx = operands[1];
6135 gen_rtx_SET (VOIDmode, operands[0],
6136 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6137 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6139 sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6144 (define_insn "*call_value_address_sp32"
6145 [(set (match_operand 0 "" "=rf")
6146 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6147 (match_operand 2 "" "")))
6148 (clobber (reg:SI 15))]
6149 ;;- Do not use operand 2 for most machines.
6152 [(set_attr "type" "call")])
6154 (define_insn "*call_value_symbolic_sp32"
6155 [(set (match_operand 0 "" "=rf")
6156 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6157 (match_operand 2 "" "")))
6158 (clobber (reg:SI 15))]
6159 ;;- Do not use operand 2 for most machines.
6162 [(set_attr "type" "call")])
6164 (define_insn "*call_value_address_sp64"
6165 [(set (match_operand 0 "" "")
6166 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6167 (match_operand 2 "" "")))
6168 (clobber (reg:DI 15))]
6169 ;;- Do not use operand 2 for most machines.
6172 [(set_attr "type" "call")])
6174 (define_insn "*call_value_symbolic_sp64"
6175 [(set (match_operand 0 "" "")
6176 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6177 (match_operand 2 "" "")))
6178 (clobber (reg:DI 15))]
6179 ;;- Do not use operand 2 for most machines.
6182 [(set_attr "type" "call")])
6184 (define_expand "untyped_call"
6185 [(parallel [(call (match_operand 0 "" "")
6187 (match_operand:BLK 1 "memory_operand" "")
6188 (match_operand 2 "" "")])]
6191 rtx valreg1 = gen_rtx_REG (DImode, 8);
6192 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6193 rtx result = operands[1];
6195 /* Pass constm1 to indicate that it may expect a structure value, but
6196 we don't know what size it is. */
6197 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6199 /* Save the function value registers. */
6200 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6201 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6204 /* The optimizer does not know that the call sets the function value
6205 registers we stored in the result block. We avoid problems by
6206 claiming that all hard registers are used and clobbered at this
6208 emit_insn (gen_blockage ());
6213 ;; Tail call instructions.
6215 (define_expand "sibcall"
6216 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6221 (define_insn "*sibcall_symbolic_sp32"
6222 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6223 (match_operand 1 "" ""))
6226 "* return output_sibcall(insn, operands[0]);"
6227 [(set_attr "type" "sibcall")])
6229 (define_insn "*sibcall_symbolic_sp64"
6230 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6231 (match_operand 1 "" ""))
6234 "* return output_sibcall(insn, operands[0]);"
6235 [(set_attr "type" "sibcall")])
6237 (define_expand "sibcall_value"
6238 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6239 (call (match_operand 1 "" "") (const_int 0)))
6244 (define_insn "*sibcall_value_symbolic_sp32"
6245 [(set (match_operand 0 "" "=rf")
6246 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6247 (match_operand 2 "" "")))
6250 "* return output_sibcall(insn, operands[1]);"
6251 [(set_attr "type" "sibcall")])
6253 (define_insn "*sibcall_value_symbolic_sp64"
6254 [(set (match_operand 0 "" "")
6255 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6256 (match_operand 2 "" "")))
6259 "* return output_sibcall(insn, operands[1]);"
6260 [(set_attr "type" "sibcall")])
6263 ;; Special instructions.
6265 (define_expand "prologue"
6269 sparc_expand_prologue ();
6273 ;; The "save register window" insn is modelled as follows so that the DWARF-2
6274 ;; backend automatically emits the required call frame debugging information
6275 ;; while it is parsing it. Therefore, the pattern should not be modified
6276 ;; without first studying the impact of the changes on the debug info.
6277 ;; [(set (%fp) (%sp))
6278 ;; (set (%sp) (unspec_volatile [(%sp) (-frame_size)] UNSPECV_SAVEW))
6279 ;; (set (%i7) (%o7))]
6281 (define_insn "save_register_window<P:mode>"
6282 [(set (reg:P 30) (reg:P 14))
6283 (set (reg:P 14) (unspec_volatile:P [(reg:P 14)
6284 (match_operand:P 0 "arith_operand" "rI")] UNSPECV_SAVEW))
6285 (set (reg:P 31) (reg:P 15))]
6287 "save\t%%sp, %0, %%sp"
6288 [(set_attr "type" "savew")])
6290 (define_expand "epilogue"
6294 sparc_expand_epilogue ();
6297 (define_expand "sibcall_epilogue"
6301 sparc_expand_epilogue ();
6305 (define_expand "return"
6307 "sparc_can_use_return_insn_p ()"
6310 (define_insn "*return_internal"
6313 "* return output_return (insn);"
6314 [(set_attr "type" "return")
6315 (set (attr "length")
6316 (cond [(eq_attr "leaf_function" "true")
6317 (if_then_else (eq_attr "empty_delay_slot" "true")
6320 (eq_attr "calls_eh_return" "true")
6321 (if_then_else (eq_attr "delayed_branch" "true")
6322 (if_then_else (eq_attr "isa" "v9")
6325 (if_then_else (eq_attr "isa" "v9")
6328 (eq_attr "empty_delay_slot" "true")
6329 (if_then_else (eq_attr "delayed_branch" "true")
6334 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6335 ;; all of memory. This blocks insns from being moved across this point.
6337 (define_insn "blockage"
6338 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6341 [(set_attr "length" "0")])
6343 (define_expand "probe_stack"
6344 [(set (match_operand 0 "memory_operand" "") (const_int 0))]
6348 = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
6351 (define_insn "probe_stack_range<P:mode>"
6352 [(set (match_operand:P 0 "register_operand" "=r")
6353 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6354 (match_operand:P 2 "register_operand" "r")]
6355 UNSPECV_PROBE_STACK_RANGE))]
6357 "* return output_probe_stack_range (operands[0], operands[2]);"
6358 [(set_attr "type" "multi")])
6360 ;; Prepare to return any type including a structure value.
6362 (define_expand "untyped_return"
6363 [(match_operand:BLK 0 "memory_operand" "")
6364 (match_operand 1 "" "")]
6367 rtx valreg1 = gen_rtx_REG (DImode, 24);
6368 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6369 rtx result = operands[0];
6371 if (! TARGET_ARCH64)
6373 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
6375 rtx value = gen_reg_rtx (SImode);
6377 /* Fetch the instruction where we will return to and see if it's an unimp
6378 instruction (the most significant 10 bits will be zero). If so,
6379 update the return address to skip the unimp instruction. */
6380 emit_move_insn (value,
6381 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
6382 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6383 emit_insn (gen_update_return (rtnreg, value));
6386 /* Reload the function value registers. */
6387 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6388 emit_move_insn (valreg2,
6389 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6391 /* Put USE insns before the return. */
6395 /* Construct the return. */
6396 expand_naked_return ();
6401 ;; Adjust the return address conditionally. If the value of op1 is equal
6402 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6403 ;; This is technically *half* the check required by the 32-bit SPARC
6404 ;; psABI. This check only ensures that an "unimp" insn was written by
6405 ;; the caller, but doesn't check to see if the expected size matches
6406 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6407 ;; only used by the above code "untyped_return".
6409 (define_insn "update_return"
6410 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6411 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6414 if (flag_delayed_branch)
6415 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6417 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6419 [(set (attr "type") (const_string "multi"))
6420 (set (attr "length")
6421 (if_then_else (eq_attr "delayed_branch" "true")
6430 (define_expand "indirect_jump"
6431 [(set (pc) (match_operand 0 "address_operand" "p"))]
6435 (define_insn "*branch_sp32"
6436 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6439 [(set_attr "type" "uncond_branch")])
6441 (define_insn "*branch_sp64"
6442 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6445 [(set_attr "type" "uncond_branch")])
6447 (define_expand "nonlocal_goto"
6448 [(match_operand:SI 0 "general_operand" "")
6449 (match_operand:SI 1 "general_operand" "")
6450 (match_operand:SI 2 "general_operand" "")
6451 (match_operand:SI 3 "" "")]
6454 rtx lab = operands[1];
6455 rtx stack = operands[2];
6456 rtx fp = operands[3];
6459 /* Trap instruction to flush all the register windows. */
6460 emit_insn (gen_flush_register_windows ());
6462 /* Load the fp value for the containing fn into %fp. This is needed
6463 because STACK refers to %fp. Note that virtual register instantiation
6464 fails if the virtual %fp isn't set from a register. */
6465 if (GET_CODE (fp) != REG)
6466 fp = force_reg (Pmode, fp);
6467 emit_move_insn (virtual_stack_vars_rtx, fp);
6469 /* Find the containing function's current nonlocal goto handler,
6470 which will do any cleanups and then jump to the label. */
6471 labreg = gen_rtx_REG (Pmode, 8);
6472 emit_move_insn (labreg, lab);
6474 /* Restore %fp from stack pointer value for containing function.
6475 The restore insn that follows will move this to %sp,
6476 and reload the appropriate value into %fp. */
6477 emit_move_insn (hard_frame_pointer_rtx, stack);
6479 emit_use (stack_pointer_rtx);
6481 /* ??? The V9-specific version was disabled in rev 1.65. */
6482 emit_jump_insn (gen_goto_handler_and_restore (labreg));
6487 ;; Special trap insn to flush register windows.
6488 (define_insn "flush_register_windows"
6489 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
6491 { return TARGET_V9 ? "flushw" : "ta\t3"; }
6492 [(set_attr "type" "flushw")])
6494 (define_insn "goto_handler_and_restore"
6495 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
6496 "GET_MODE (operands[0]) == Pmode"
6498 if (flag_delayed_branch)
6499 return "jmp\t%0\n\t restore";
6501 return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
6503 [(set (attr "type") (const_string "multi"))
6504 (set (attr "length")
6505 (if_then_else (eq_attr "delayed_branch" "true")
6509 ;; For __builtin_setjmp we need to flush register windows iff the function
6510 ;; calls alloca as well, because otherwise the register window might be
6511 ;; saved after %sp adjustment and thus setjmp would crash
6512 (define_expand "builtin_setjmp_setup"
6513 [(match_operand 0 "register_operand" "r")]
6516 emit_insn (gen_do_builtin_setjmp_setup ());
6520 (define_insn "do_builtin_setjmp_setup"
6521 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
6524 if (!cfun->calls_alloca)
6528 fputs ("\tflushw\n", asm_out_file);
6530 fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
6531 TARGET_ARCH64 ? 'x' : 'w',
6532 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
6533 fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
6534 TARGET_ARCH64 ? 'x' : 'w',
6535 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
6536 fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
6537 TARGET_ARCH64 ? 'x' : 'w',
6538 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
6541 [(set_attr "type" "multi")
6542 (set (attr "length")
6543 (cond [(eq_attr "calls_alloca" "false")
6545 (eq_attr "isa" "!v9")
6547 (eq_attr "pic" "true")
6548 (const_int 4)] (const_int 3)))])
6550 ;; Pattern for use after a setjmp to store FP and the return register
6551 ;; into the stack area.
6553 (define_expand "setjmp"
6559 mem = gen_rtx_MEM (Pmode,
6560 plus_constant (stack_pointer_rtx,
6561 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD));
6562 emit_insn (gen_rtx_SET (VOIDmode, mem, frame_pointer_rtx));
6564 mem = gen_rtx_MEM (Pmode,
6565 plus_constant (stack_pointer_rtx,
6566 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD));
6567 emit_insn (gen_rtx_SET (VOIDmode, mem, gen_rtx_REG (Pmode, 31)));
6571 ;; Special pattern for the FLUSH instruction.
6573 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
6574 ; of the define_insn otherwise missing a mode. We make "flush", aka
6575 ; gen_flush, the default one since sparc_initialize_trampoline uses
6576 ; it on SImode mem values.
6578 (define_insn "flush"
6579 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6581 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6582 [(set_attr "type" "iflush")])
6584 (define_insn "flushdi"
6585 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6587 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6588 [(set_attr "type" "iflush")])
6591 ;; Find first set instructions.
6593 ;; The scan instruction searches from the most significant bit while ffs
6594 ;; searches from the least significant bit. The bit index and treatment of
6595 ;; zero also differ. It takes at least 7 instructions to get the proper
6596 ;; result. Here is an obvious 8 instruction sequence.
6599 (define_insn "ffssi2"
6600 [(set (match_operand:SI 0 "register_operand" "=&r")
6601 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
6602 (clobber (match_scratch:SI 2 "=&r"))]
6603 "TARGET_SPARCLITE || TARGET_SPARCLET"
6605 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";
6607 [(set_attr "type" "multi")
6608 (set_attr "length" "8")])
6610 ;; ??? This should be a define expand, so that the extra instruction have
6611 ;; a chance of being optimized away.
6613 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
6614 ;; does, but no one uses that and we don't have a switch for it.
6616 ;(define_insn "ffsdi2"
6617 ; [(set (match_operand:DI 0 "register_operand" "=&r")
6618 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
6619 ; (clobber (match_scratch:DI 2 "=&r"))]
6621 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
6622 ; [(set_attr "type" "multi")
6623 ; (set_attr "length" "4")])
6627 ;; Peepholes go at the end.
6629 ;; Optimize consecutive loads or stores into ldd and std when possible.
6630 ;; The conditions in which we do this are very restricted and are
6631 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
6634 [(set (match_operand:SI 0 "memory_operand" "")
6636 (set (match_operand:SI 1 "memory_operand" "")
6639 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
6642 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
6645 [(set (match_operand:SI 0 "memory_operand" "")
6647 (set (match_operand:SI 1 "memory_operand" "")
6650 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
6653 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
6656 [(set (match_operand:SI 0 "register_operand" "")
6657 (match_operand:SI 1 "memory_operand" ""))
6658 (set (match_operand:SI 2 "register_operand" "")
6659 (match_operand:SI 3 "memory_operand" ""))]
6660 "registers_ok_for_ldd_peep (operands[0], operands[2])
6661 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6664 "operands[1] = widen_memory_access (operands[1], DImode, 0);
6665 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
6668 [(set (match_operand:SI 0 "memory_operand" "")
6669 (match_operand:SI 1 "register_operand" ""))
6670 (set (match_operand:SI 2 "memory_operand" "")
6671 (match_operand:SI 3 "register_operand" ""))]
6672 "registers_ok_for_ldd_peep (operands[1], operands[3])
6673 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6676 "operands[0] = widen_memory_access (operands[0], DImode, 0);
6677 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
6680 [(set (match_operand:SF 0 "register_operand" "")
6681 (match_operand:SF 1 "memory_operand" ""))
6682 (set (match_operand:SF 2 "register_operand" "")
6683 (match_operand:SF 3 "memory_operand" ""))]
6684 "registers_ok_for_ldd_peep (operands[0], operands[2])
6685 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6688 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
6689 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
6692 [(set (match_operand:SF 0 "memory_operand" "")
6693 (match_operand:SF 1 "register_operand" ""))
6694 (set (match_operand:SF 2 "memory_operand" "")
6695 (match_operand:SF 3 "register_operand" ""))]
6696 "registers_ok_for_ldd_peep (operands[1], operands[3])
6697 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6700 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
6701 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
6704 [(set (match_operand:SI 0 "register_operand" "")
6705 (match_operand:SI 1 "memory_operand" ""))
6706 (set (match_operand:SI 2 "register_operand" "")
6707 (match_operand:SI 3 "memory_operand" ""))]
6708 "registers_ok_for_ldd_peep (operands[2], operands[0])
6709 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6712 "operands[3] = widen_memory_access (operands[3], DImode, 0);
6713 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
6716 [(set (match_operand:SI 0 "memory_operand" "")
6717 (match_operand:SI 1 "register_operand" ""))
6718 (set (match_operand:SI 2 "memory_operand" "")
6719 (match_operand:SI 3 "register_operand" ""))]
6720 "registers_ok_for_ldd_peep (operands[3], operands[1])
6721 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6724 "operands[2] = widen_memory_access (operands[2], DImode, 0);
6725 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
6729 [(set (match_operand:SF 0 "register_operand" "")
6730 (match_operand:SF 1 "memory_operand" ""))
6731 (set (match_operand:SF 2 "register_operand" "")
6732 (match_operand:SF 3 "memory_operand" ""))]
6733 "registers_ok_for_ldd_peep (operands[2], operands[0])
6734 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6737 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
6738 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
6741 [(set (match_operand:SF 0 "memory_operand" "")
6742 (match_operand:SF 1 "register_operand" ""))
6743 (set (match_operand:SF 2 "memory_operand" "")
6744 (match_operand:SF 3 "register_operand" ""))]
6745 "registers_ok_for_ldd_peep (operands[3], operands[1])
6746 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6749 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
6750 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
6752 ;; Optimize the case of following a reg-reg move with a test
6753 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
6754 ;; This can result from a float to fix conversion.
6757 [(set (match_operand:SI 0 "register_operand" "")
6758 (match_operand:SI 1 "register_operand" ""))
6760 (compare:CC (match_operand:SI 2 "register_operand" "")
6762 "(rtx_equal_p (operands[2], operands[0])
6763 || rtx_equal_p (operands[2], operands[1]))
6764 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6765 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6766 [(parallel [(set (match_dup 0) (match_dup 1))
6768 (compare:CC (match_dup 1) (const_int 0)))])]
6772 [(set (match_operand:DI 0 "register_operand" "")
6773 (match_operand:DI 1 "register_operand" ""))
6775 (compare:CCX (match_operand:DI 2 "register_operand" "")
6778 && (rtx_equal_p (operands[2], operands[0])
6779 || rtx_equal_p (operands[2], operands[1]))
6780 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6781 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6782 [(parallel [(set (match_dup 0) (match_dup 1))
6784 (compare:CCX (match_dup 1) (const_int 0)))])]
6788 ;; Prefetch instructions.
6790 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
6791 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
6792 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
6794 (define_expand "prefetch"
6795 [(match_operand 0 "address_operand" "")
6796 (match_operand 1 "const_int_operand" "")
6797 (match_operand 2 "const_int_operand" "")]
6801 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
6803 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
6807 (define_insn "prefetch_64"
6808 [(prefetch (match_operand:DI 0 "address_operand" "p")
6809 (match_operand:DI 1 "const_int_operand" "n")
6810 (match_operand:DI 2 "const_int_operand" "n"))]
6813 static const char * const prefetch_instr[2][2] = {
6815 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
6816 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
6819 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
6820 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
6823 int read_or_write = INTVAL (operands[1]);
6824 int locality = INTVAL (operands[2]);
6826 gcc_assert (read_or_write == 0 || read_or_write == 1);
6827 gcc_assert (locality >= 0 && locality < 4);
6828 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
6830 [(set_attr "type" "load")])
6832 (define_insn "prefetch_32"
6833 [(prefetch (match_operand:SI 0 "address_operand" "p")
6834 (match_operand:SI 1 "const_int_operand" "n")
6835 (match_operand:SI 2 "const_int_operand" "n"))]
6838 static const char * const prefetch_instr[2][2] = {
6840 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
6841 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
6844 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
6845 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
6848 int read_or_write = INTVAL (operands[1]);
6849 int locality = INTVAL (operands[2]);
6851 gcc_assert (read_or_write == 0 || read_or_write == 1);
6852 gcc_assert (locality >= 0 && locality < 4);
6853 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
6855 [(set_attr "type" "load")])
6858 ;; Trap instructions.
6861 [(trap_if (const_int 1) (const_int 5))]
6864 [(set_attr "type" "trap")])
6866 (define_expand "ctrapsi4"
6867 [(trap_if (match_operator 0 "noov_compare_operator"
6868 [(match_operand:SI 1 "compare_operand" "")
6869 (match_operand:SI 2 "arith_operand" "")])
6870 (match_operand 3 ""))]
6872 "operands[1] = gen_compare_reg (operands[0]);
6873 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
6875 operands[2] = const0_rtx;")
6877 (define_expand "ctrapdi4"
6878 [(trap_if (match_operator 0 "noov_compare_operator"
6879 [(match_operand:DI 1 "compare_operand" "")
6880 (match_operand:DI 2 "arith_operand" "")])
6881 (match_operand 3 ""))]
6883 "operands[1] = gen_compare_reg (operands[0]);
6884 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
6886 operands[2] = const0_rtx;")
6890 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC 100) (const_int 0)])
6891 (match_operand:SI 1 "arith_operand" "rM"))]
6895 return "t%C0\t%%icc, %1";
6899 [(set_attr "type" "trap")])
6902 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX 100) (const_int 0)])
6903 (match_operand:SI 1 "arith_operand" "rM"))]
6906 [(set_attr "type" "trap")])
6909 ;; TLS support instructions.
6911 (define_insn "tgd_hi22"
6912 [(set (match_operand:SI 0 "register_operand" "=r")
6913 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
6916 "sethi\\t%%tgd_hi22(%a1), %0")
6918 (define_insn "tgd_lo10"
6919 [(set (match_operand:SI 0 "register_operand" "=r")
6920 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
6921 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
6924 "add\\t%1, %%tgd_lo10(%a2), %0")
6926 (define_insn "tgd_add32"
6927 [(set (match_operand:SI 0 "register_operand" "=r")
6928 (plus:SI (match_operand:SI 1 "register_operand" "r")
6929 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
6930 (match_operand 3 "tgd_symbolic_operand" "")]
6932 "TARGET_TLS && TARGET_ARCH32"
6933 "add\\t%1, %2, %0, %%tgd_add(%a3)")
6935 (define_insn "tgd_add64"
6936 [(set (match_operand:DI 0 "register_operand" "=r")
6937 (plus:DI (match_operand:DI 1 "register_operand" "r")
6938 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
6939 (match_operand 3 "tgd_symbolic_operand" "")]
6941 "TARGET_TLS && TARGET_ARCH64"
6942 "add\\t%1, %2, %0, %%tgd_add(%a3)")
6944 (define_insn "tgd_call32"
6945 [(set (match_operand 0 "register_operand" "=r")
6946 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
6947 (match_operand 2 "tgd_symbolic_operand" "")]
6949 (match_operand 3 "" "")))
6950 (clobber (reg:SI 15))]
6951 "TARGET_TLS && TARGET_ARCH32"
6952 "call\t%a1, %%tgd_call(%a2)%#"
6953 [(set_attr "type" "call")])
6955 (define_insn "tgd_call64"
6956 [(set (match_operand 0 "register_operand" "=r")
6957 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
6958 (match_operand 2 "tgd_symbolic_operand" "")]
6960 (match_operand 3 "" "")))
6961 (clobber (reg:DI 15))]
6962 "TARGET_TLS && TARGET_ARCH64"
6963 "call\t%a1, %%tgd_call(%a2)%#"
6964 [(set_attr "type" "call")])
6966 (define_insn "tldm_hi22"
6967 [(set (match_operand:SI 0 "register_operand" "=r")
6968 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
6970 "sethi\\t%%tldm_hi22(%&), %0")
6972 (define_insn "tldm_lo10"
6973 [(set (match_operand:SI 0 "register_operand" "=r")
6974 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
6975 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
6977 "add\\t%1, %%tldm_lo10(%&), %0")
6979 (define_insn "tldm_add32"
6980 [(set (match_operand:SI 0 "register_operand" "=r")
6981 (plus:SI (match_operand:SI 1 "register_operand" "r")
6982 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
6984 "TARGET_TLS && TARGET_ARCH32"
6985 "add\\t%1, %2, %0, %%tldm_add(%&)")
6987 (define_insn "tldm_add64"
6988 [(set (match_operand:DI 0 "register_operand" "=r")
6989 (plus:DI (match_operand:DI 1 "register_operand" "r")
6990 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
6992 "TARGET_TLS && TARGET_ARCH64"
6993 "add\\t%1, %2, %0, %%tldm_add(%&)")
6995 (define_insn "tldm_call32"
6996 [(set (match_operand 0 "register_operand" "=r")
6997 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
6999 (match_operand 2 "" "")))
7000 (clobber (reg:SI 15))]
7001 "TARGET_TLS && TARGET_ARCH32"
7002 "call\t%a1, %%tldm_call(%&)%#"
7003 [(set_attr "type" "call")])
7005 (define_insn "tldm_call64"
7006 [(set (match_operand 0 "register_operand" "=r")
7007 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7009 (match_operand 2 "" "")))
7010 (clobber (reg:DI 15))]
7011 "TARGET_TLS && TARGET_ARCH64"
7012 "call\t%a1, %%tldm_call(%&)%#"
7013 [(set_attr "type" "call")])
7015 (define_insn "tldo_hix22"
7016 [(set (match_operand:SI 0 "register_operand" "=r")
7017 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7020 "sethi\\t%%tldo_hix22(%a1), %0")
7022 (define_insn "tldo_lox10"
7023 [(set (match_operand:SI 0 "register_operand" "=r")
7024 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7025 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7028 "xor\\t%1, %%tldo_lox10(%a2), %0")
7030 (define_insn "tldo_add32"
7031 [(set (match_operand:SI 0 "register_operand" "=r")
7032 (plus:SI (match_operand:SI 1 "register_operand" "r")
7033 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7034 (match_operand 3 "tld_symbolic_operand" "")]
7036 "TARGET_TLS && TARGET_ARCH32"
7037 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7039 (define_insn "tldo_add64"
7040 [(set (match_operand:DI 0 "register_operand" "=r")
7041 (plus:DI (match_operand:DI 1 "register_operand" "r")
7042 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7043 (match_operand 3 "tld_symbolic_operand" "")]
7045 "TARGET_TLS && TARGET_ARCH64"
7046 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7048 (define_insn "tie_hi22"
7049 [(set (match_operand:SI 0 "register_operand" "=r")
7050 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7053 "sethi\\t%%tie_hi22(%a1), %0")
7055 (define_insn "tie_lo10"
7056 [(set (match_operand:SI 0 "register_operand" "=r")
7057 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7058 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7061 "add\\t%1, %%tie_lo10(%a2), %0")
7063 (define_insn "tie_ld32"
7064 [(set (match_operand:SI 0 "register_operand" "=r")
7065 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7066 (match_operand:SI 2 "register_operand" "r")
7067 (match_operand 3 "tie_symbolic_operand" "")]
7069 "TARGET_TLS && TARGET_ARCH32"
7070 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7071 [(set_attr "type" "load")])
7073 (define_insn "tie_ld64"
7074 [(set (match_operand:DI 0 "register_operand" "=r")
7075 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7076 (match_operand:SI 2 "register_operand" "r")
7077 (match_operand 3 "tie_symbolic_operand" "")]
7079 "TARGET_TLS && TARGET_ARCH64"
7080 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7081 [(set_attr "type" "load")])
7083 (define_insn "tie_add32"
7084 [(set (match_operand:SI 0 "register_operand" "=r")
7085 (plus:SI (match_operand:SI 1 "register_operand" "r")
7086 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7087 (match_operand 3 "tie_symbolic_operand" "")]
7089 "TARGET_SUN_TLS && TARGET_ARCH32"
7090 "add\\t%1, %2, %0, %%tie_add(%a3)")
7092 (define_insn "tie_add64"
7093 [(set (match_operand:DI 0 "register_operand" "=r")
7094 (plus:DI (match_operand:DI 1 "register_operand" "r")
7095 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7096 (match_operand 3 "tie_symbolic_operand" "")]
7098 "TARGET_SUN_TLS && TARGET_ARCH64"
7099 "add\\t%1, %2, %0, %%tie_add(%a3)")
7101 (define_insn "tle_hix22_sp32"
7102 [(set (match_operand:SI 0 "register_operand" "=r")
7103 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7105 "TARGET_TLS && TARGET_ARCH32"
7106 "sethi\\t%%tle_hix22(%a1), %0")
7108 (define_insn "tle_lox10_sp32"
7109 [(set (match_operand:SI 0 "register_operand" "=r")
7110 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7111 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7113 "TARGET_TLS && TARGET_ARCH32"
7114 "xor\\t%1, %%tle_lox10(%a2), %0")
7116 (define_insn "tle_hix22_sp64"
7117 [(set (match_operand:DI 0 "register_operand" "=r")
7118 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7120 "TARGET_TLS && TARGET_ARCH64"
7121 "sethi\\t%%tle_hix22(%a1), %0")
7123 (define_insn "tle_lox10_sp64"
7124 [(set (match_operand:DI 0 "register_operand" "=r")
7125 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7126 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7128 "TARGET_TLS && TARGET_ARCH64"
7129 "xor\\t%1, %%tle_lox10(%a2), %0")
7131 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7132 (define_insn "*tldo_ldub_sp32"
7133 [(set (match_operand:QI 0 "register_operand" "=r")
7134 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7135 (match_operand 3 "tld_symbolic_operand" "")]
7137 (match_operand:SI 1 "register_operand" "r"))))]
7138 "TARGET_TLS && TARGET_ARCH32"
7139 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7140 [(set_attr "type" "load")
7141 (set_attr "us3load_type" "3cycle")])
7143 (define_insn "*tldo_ldub1_sp32"
7144 [(set (match_operand:HI 0 "register_operand" "=r")
7145 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7146 (match_operand 3 "tld_symbolic_operand" "")]
7148 (match_operand:SI 1 "register_operand" "r")))))]
7149 "TARGET_TLS && TARGET_ARCH32"
7150 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7151 [(set_attr "type" "load")
7152 (set_attr "us3load_type" "3cycle")])
7154 (define_insn "*tldo_ldub2_sp32"
7155 [(set (match_operand:SI 0 "register_operand" "=r")
7156 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7157 (match_operand 3 "tld_symbolic_operand" "")]
7159 (match_operand:SI 1 "register_operand" "r")))))]
7160 "TARGET_TLS && TARGET_ARCH32"
7161 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7162 [(set_attr "type" "load")
7163 (set_attr "us3load_type" "3cycle")])
7165 (define_insn "*tldo_ldsb1_sp32"
7166 [(set (match_operand:HI 0 "register_operand" "=r")
7167 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7168 (match_operand 3 "tld_symbolic_operand" "")]
7170 (match_operand:SI 1 "register_operand" "r")))))]
7171 "TARGET_TLS && TARGET_ARCH32"
7172 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7173 [(set_attr "type" "sload")
7174 (set_attr "us3load_type" "3cycle")])
7176 (define_insn "*tldo_ldsb2_sp32"
7177 [(set (match_operand:SI 0 "register_operand" "=r")
7178 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7179 (match_operand 3 "tld_symbolic_operand" "")]
7181 (match_operand:SI 1 "register_operand" "r")))))]
7182 "TARGET_TLS && TARGET_ARCH32"
7183 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7184 [(set_attr "type" "sload")
7185 (set_attr "us3load_type" "3cycle")])
7187 (define_insn "*tldo_ldub_sp64"
7188 [(set (match_operand:QI 0 "register_operand" "=r")
7189 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7190 (match_operand 3 "tld_symbolic_operand" "")]
7192 (match_operand:DI 1 "register_operand" "r"))))]
7193 "TARGET_TLS && TARGET_ARCH64"
7194 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7195 [(set_attr "type" "load")
7196 (set_attr "us3load_type" "3cycle")])
7198 (define_insn "*tldo_ldub1_sp64"
7199 [(set (match_operand:HI 0 "register_operand" "=r")
7200 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7201 (match_operand 3 "tld_symbolic_operand" "")]
7203 (match_operand:DI 1 "register_operand" "r")))))]
7204 "TARGET_TLS && TARGET_ARCH64"
7205 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7206 [(set_attr "type" "load")
7207 (set_attr "us3load_type" "3cycle")])
7209 (define_insn "*tldo_ldub2_sp64"
7210 [(set (match_operand:SI 0 "register_operand" "=r")
7211 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7212 (match_operand 3 "tld_symbolic_operand" "")]
7214 (match_operand:DI 1 "register_operand" "r")))))]
7215 "TARGET_TLS && TARGET_ARCH64"
7216 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7217 [(set_attr "type" "load")
7218 (set_attr "us3load_type" "3cycle")])
7220 (define_insn "*tldo_ldub3_sp64"
7221 [(set (match_operand:DI 0 "register_operand" "=r")
7222 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7223 (match_operand 3 "tld_symbolic_operand" "")]
7225 (match_operand:DI 1 "register_operand" "r")))))]
7226 "TARGET_TLS && TARGET_ARCH64"
7227 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7228 [(set_attr "type" "load")
7229 (set_attr "us3load_type" "3cycle")])
7231 (define_insn "*tldo_ldsb1_sp64"
7232 [(set (match_operand:HI 0 "register_operand" "=r")
7233 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7234 (match_operand 3 "tld_symbolic_operand" "")]
7236 (match_operand:DI 1 "register_operand" "r")))))]
7237 "TARGET_TLS && TARGET_ARCH64"
7238 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7239 [(set_attr "type" "sload")
7240 (set_attr "us3load_type" "3cycle")])
7242 (define_insn "*tldo_ldsb2_sp64"
7243 [(set (match_operand:SI 0 "register_operand" "=r")
7244 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7245 (match_operand 3 "tld_symbolic_operand" "")]
7247 (match_operand:DI 1 "register_operand" "r")))))]
7248 "TARGET_TLS && TARGET_ARCH64"
7249 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7250 [(set_attr "type" "sload")
7251 (set_attr "us3load_type" "3cycle")])
7253 (define_insn "*tldo_ldsb3_sp64"
7254 [(set (match_operand:DI 0 "register_operand" "=r")
7255 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7256 (match_operand 3 "tld_symbolic_operand" "")]
7258 (match_operand:DI 1 "register_operand" "r")))))]
7259 "TARGET_TLS && TARGET_ARCH64"
7260 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7261 [(set_attr "type" "sload")
7262 (set_attr "us3load_type" "3cycle")])
7264 (define_insn "*tldo_lduh_sp32"
7265 [(set (match_operand:HI 0 "register_operand" "=r")
7266 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7267 (match_operand 3 "tld_symbolic_operand" "")]
7269 (match_operand:SI 1 "register_operand" "r"))))]
7270 "TARGET_TLS && TARGET_ARCH32"
7271 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7272 [(set_attr "type" "load")
7273 (set_attr "us3load_type" "3cycle")])
7275 (define_insn "*tldo_lduh1_sp32"
7276 [(set (match_operand:SI 0 "register_operand" "=r")
7277 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7278 (match_operand 3 "tld_symbolic_operand" "")]
7280 (match_operand:SI 1 "register_operand" "r")))))]
7281 "TARGET_TLS && TARGET_ARCH32"
7282 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7283 [(set_attr "type" "load")
7284 (set_attr "us3load_type" "3cycle")])
7286 (define_insn "*tldo_ldsh1_sp32"
7287 [(set (match_operand:SI 0 "register_operand" "=r")
7288 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7289 (match_operand 3 "tld_symbolic_operand" "")]
7291 (match_operand:SI 1 "register_operand" "r")))))]
7292 "TARGET_TLS && TARGET_ARCH32"
7293 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7294 [(set_attr "type" "sload")
7295 (set_attr "us3load_type" "3cycle")])
7297 (define_insn "*tldo_lduh_sp64"
7298 [(set (match_operand:HI 0 "register_operand" "=r")
7299 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7300 (match_operand 3 "tld_symbolic_operand" "")]
7302 (match_operand:DI 1 "register_operand" "r"))))]
7303 "TARGET_TLS && TARGET_ARCH64"
7304 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7305 [(set_attr "type" "load")
7306 (set_attr "us3load_type" "3cycle")])
7308 (define_insn "*tldo_lduh1_sp64"
7309 [(set (match_operand:SI 0 "register_operand" "=r")
7310 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7311 (match_operand 3 "tld_symbolic_operand" "")]
7313 (match_operand:DI 1 "register_operand" "r")))))]
7314 "TARGET_TLS && TARGET_ARCH64"
7315 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7316 [(set_attr "type" "load")
7317 (set_attr "us3load_type" "3cycle")])
7319 (define_insn "*tldo_lduh2_sp64"
7320 [(set (match_operand:DI 0 "register_operand" "=r")
7321 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7322 (match_operand 3 "tld_symbolic_operand" "")]
7324 (match_operand:DI 1 "register_operand" "r")))))]
7325 "TARGET_TLS && TARGET_ARCH64"
7326 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7327 [(set_attr "type" "load")
7328 (set_attr "us3load_type" "3cycle")])
7330 (define_insn "*tldo_ldsh1_sp64"
7331 [(set (match_operand:SI 0 "register_operand" "=r")
7332 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7333 (match_operand 3 "tld_symbolic_operand" "")]
7335 (match_operand:DI 1 "register_operand" "r")))))]
7336 "TARGET_TLS && TARGET_ARCH64"
7337 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7338 [(set_attr "type" "sload")
7339 (set_attr "us3load_type" "3cycle")])
7341 (define_insn "*tldo_ldsh2_sp64"
7342 [(set (match_operand:DI 0 "register_operand" "=r")
7343 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7344 (match_operand 3 "tld_symbolic_operand" "")]
7346 (match_operand:DI 1 "register_operand" "r")))))]
7347 "TARGET_TLS && TARGET_ARCH64"
7348 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7349 [(set_attr "type" "sload")
7350 (set_attr "us3load_type" "3cycle")])
7352 (define_insn "*tldo_lduw_sp32"
7353 [(set (match_operand:SI 0 "register_operand" "=r")
7354 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7355 (match_operand 3 "tld_symbolic_operand" "")]
7357 (match_operand:SI 1 "register_operand" "r"))))]
7358 "TARGET_TLS && TARGET_ARCH32"
7359 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7360 [(set_attr "type" "load")])
7362 (define_insn "*tldo_lduw_sp64"
7363 [(set (match_operand:SI 0 "register_operand" "=r")
7364 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7365 (match_operand 3 "tld_symbolic_operand" "")]
7367 (match_operand:DI 1 "register_operand" "r"))))]
7368 "TARGET_TLS && TARGET_ARCH64"
7369 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7370 [(set_attr "type" "load")])
7372 (define_insn "*tldo_lduw1_sp64"
7373 [(set (match_operand:DI 0 "register_operand" "=r")
7374 (zero_extend:DI (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_ldsw1_sp64"
7383 [(set (match_operand:DI 0 "register_operand" "=r")
7384 (sign_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 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7390 [(set_attr "type" "sload")
7391 (set_attr "us3load_type" "3cycle")])
7393 (define_insn "*tldo_ldx_sp64"
7394 [(set (match_operand:DI 0 "register_operand" "=r")
7395 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7396 (match_operand 3 "tld_symbolic_operand" "")]
7398 (match_operand:DI 1 "register_operand" "r"))))]
7399 "TARGET_TLS && TARGET_ARCH64"
7400 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7401 [(set_attr "type" "load")])
7403 (define_insn "*tldo_stb_sp32"
7404 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7405 (match_operand 3 "tld_symbolic_operand" "")]
7407 (match_operand:SI 1 "register_operand" "r")))
7408 (match_operand:QI 0 "register_operand" "=r"))]
7409 "TARGET_TLS && TARGET_ARCH32"
7410 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7411 [(set_attr "type" "store")])
7413 (define_insn "*tldo_stb_sp64"
7414 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7415 (match_operand 3 "tld_symbolic_operand" "")]
7417 (match_operand:DI 1 "register_operand" "r")))
7418 (match_operand:QI 0 "register_operand" "=r"))]
7419 "TARGET_TLS && TARGET_ARCH64"
7420 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7421 [(set_attr "type" "store")])
7423 (define_insn "*tldo_sth_sp32"
7424 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7425 (match_operand 3 "tld_symbolic_operand" "")]
7427 (match_operand:SI 1 "register_operand" "r")))
7428 (match_operand:HI 0 "register_operand" "=r"))]
7429 "TARGET_TLS && TARGET_ARCH32"
7430 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7431 [(set_attr "type" "store")])
7433 (define_insn "*tldo_sth_sp64"
7434 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7435 (match_operand 3 "tld_symbolic_operand" "")]
7437 (match_operand:DI 1 "register_operand" "r")))
7438 (match_operand:HI 0 "register_operand" "=r"))]
7439 "TARGET_TLS && TARGET_ARCH64"
7440 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7441 [(set_attr "type" "store")])
7443 (define_insn "*tldo_stw_sp32"
7444 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7445 (match_operand 3 "tld_symbolic_operand" "")]
7447 (match_operand:SI 1 "register_operand" "r")))
7448 (match_operand:SI 0 "register_operand" "=r"))]
7449 "TARGET_TLS && TARGET_ARCH32"
7450 "st\t%0, [%1 + %2], %%tldo_add(%3)"
7451 [(set_attr "type" "store")])
7453 (define_insn "*tldo_stw_sp64"
7454 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7455 (match_operand 3 "tld_symbolic_operand" "")]
7457 (match_operand:DI 1 "register_operand" "r")))
7458 (match_operand:SI 0 "register_operand" "=r"))]
7459 "TARGET_TLS && TARGET_ARCH64"
7460 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7461 [(set_attr "type" "store")])
7463 (define_insn "*tldo_stx_sp64"
7464 [(set (mem:DI (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:DI 0 "register_operand" "=r"))]
7469 "TARGET_TLS && TARGET_ARCH64"
7470 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7471 [(set_attr "type" "store")])
7474 ;; Stack protector instructions.
7476 (define_expand "stack_protect_set"
7477 [(match_operand 0 "memory_operand" "")
7478 (match_operand 1 "memory_operand" "")]
7481 #ifdef TARGET_THREAD_SSP_OFFSET
7482 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7483 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7484 operands[1] = gen_rtx_MEM (Pmode, addr);
7487 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7489 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7493 (define_insn "stack_protect_setsi"
7494 [(set (match_operand:SI 0 "memory_operand" "=m")
7495 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7496 (set (match_scratch:SI 2 "=&r") (const_int 0))]
7498 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
7499 [(set_attr "type" "multi")
7500 (set_attr "length" "3")])
7502 (define_insn "stack_protect_setdi"
7503 [(set (match_operand:DI 0 "memory_operand" "=m")
7504 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7505 (set (match_scratch:DI 2 "=&r") (const_int 0))]
7507 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
7508 [(set_attr "type" "multi")
7509 (set_attr "length" "3")])
7511 (define_expand "stack_protect_test"
7512 [(match_operand 0 "memory_operand" "")
7513 (match_operand 1 "memory_operand" "")
7514 (match_operand 2 "" "")]
7518 #ifdef TARGET_THREAD_SSP_OFFSET
7519 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7520 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7521 operands[1] = gen_rtx_MEM (Pmode, addr);
7525 result = gen_reg_rtx (Pmode);
7526 emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
7527 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7528 emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
7532 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7533 result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
7534 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7535 emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
7540 (define_insn "stack_protect_testsi"
7542 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
7543 (match_operand:SI 1 "memory_operand" "m")]
7545 (set (match_scratch:SI 3 "=r") (const_int 0))
7546 (clobber (match_scratch:SI 2 "=&r"))]
7548 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
7549 [(set_attr "type" "multi")
7550 (set_attr "length" "4")])
7552 (define_insn "stack_protect_testdi"
7553 [(set (match_operand:DI 0 "register_operand" "=&r")
7554 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7555 (match_operand:DI 2 "memory_operand" "m")]
7557 (set (match_scratch:DI 3 "=r") (const_int 0))]
7559 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
7560 [(set_attr "type" "multi")
7561 (set_attr "length" "4")])
7564 ;; Vector instructions.
7566 (define_insn "addv2si3"
7567 [(set (match_operand:V2SI 0 "register_operand" "=e")
7568 (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7569 (match_operand:V2SI 2 "register_operand" "e")))]
7571 "fpadd32\t%1, %2, %0"
7572 [(set_attr "type" "fga")
7573 (set_attr "fptype" "double")])
7575 (define_insn "addv4hi3"
7576 [(set (match_operand:V4HI 0 "register_operand" "=e")
7577 (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7578 (match_operand:V4HI 2 "register_operand" "e")))]
7580 "fpadd16\t%1, %2, %0"
7581 [(set_attr "type" "fga")
7582 (set_attr "fptype" "double")])
7584 ;; fpadd32s is emitted by the addsi3 pattern.
7586 (define_insn "addv2hi3"
7587 [(set (match_operand:V2HI 0 "register_operand" "=f")
7588 (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7589 (match_operand:V2HI 2 "register_operand" "f")))]
7591 "fpadd16s\t%1, %2, %0"
7592 [(set_attr "type" "fga")
7593 (set_attr "fptype" "single")])
7595 (define_insn "subv2si3"
7596 [(set (match_operand:V2SI 0 "register_operand" "=e")
7597 (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7598 (match_operand:V2SI 2 "register_operand" "e")))]
7600 "fpsub32\t%1, %2, %0"
7601 [(set_attr "type" "fga")
7602 (set_attr "fptype" "double")])
7604 (define_insn "subv4hi3"
7605 [(set (match_operand:V4HI 0 "register_operand" "=e")
7606 (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7607 (match_operand:V4HI 2 "register_operand" "e")))]
7609 "fpsub16\t%1, %2, %0"
7610 [(set_attr "type" "fga")
7611 (set_attr "fptype" "double")])
7613 ;; fpsub32s is emitted by the subsi3 pattern.
7615 (define_insn "subv2hi3"
7616 [(set (match_operand:V2HI 0 "register_operand" "=f")
7617 (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7618 (match_operand:V2HI 2 "register_operand" "f")))]
7620 "fpsub16s\t%1, %2, %0"
7621 [(set_attr "type" "fga")
7622 (set_attr "fptype" "single")])
7624 ;; All other logical instructions have integer equivalents so they
7625 ;; are defined together.
7627 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
7629 (define_insn "*nand<V64:mode>_vis"
7630 [(set (match_operand:V64 0 "register_operand" "=e")
7631 (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
7632 (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
7635 [(set_attr "type" "fga")
7636 (set_attr "fptype" "double")])
7638 (define_insn "*nand<V32:mode>_vis"
7639 [(set (match_operand:V32 0 "register_operand" "=f")
7640 (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
7641 (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
7643 "fnands\t%1, %2, %0"
7644 [(set_attr "type" "fga")
7645 (set_attr "fptype" "single")])
7647 ;; Hard to generate VIS instructions. We have builtins for these.
7649 (define_insn "fpack16_vis"
7650 [(set (match_operand:V4QI 0 "register_operand" "=f")
7651 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
7655 [(set_attr "type" "fga")
7656 (set_attr "fptype" "double")])
7658 (define_insn "fpackfix_vis"
7659 [(set (match_operand:V2HI 0 "register_operand" "=f")
7660 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
7664 [(set_attr "type" "fga")
7665 (set_attr "fptype" "double")])
7667 (define_insn "fpack32_vis"
7668 [(set (match_operand:V8QI 0 "register_operand" "=e")
7669 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
7670 (match_operand:V8QI 2 "register_operand" "e")]
7673 "fpack32\t%1, %2, %0"
7674 [(set_attr "type" "fga")
7675 (set_attr "fptype" "double")])
7677 (define_insn "fexpand_vis"
7678 [(set (match_operand:V4HI 0 "register_operand" "=e")
7679 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
7683 [(set_attr "type" "fga")
7684 (set_attr "fptype" "double")])
7686 ;; It may be possible to describe this operation as (1 indexed):
7687 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
7688 ;; 1,5,10,14,19,23,28,32)
7689 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
7690 ;; because vec_merge expects all the operands to be of the same type.
7691 (define_insn "fpmerge_vis"
7692 [(set (match_operand:V8QI 0 "register_operand" "=e")
7693 (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
7694 (match_operand:V4QI 2 "register_operand" "f")]
7697 "fpmerge\t%1, %2, %0"
7698 [(set_attr "type" "fga")
7699 (set_attr "fptype" "double")])
7701 ;; Partitioned multiply instructions
7702 (define_insn "fmul8x16_vis"
7703 [(set (match_operand:V4HI 0 "register_operand" "=e")
7704 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7705 (match_operand:V4HI 2 "register_operand" "e")))]
7707 "fmul8x16\t%1, %2, %0"
7708 [(set_attr "type" "fpmul")
7709 (set_attr "fptype" "double")])
7711 ;; Only one of the following two insns can be a multiply.
7712 (define_insn "fmul8x16au_vis"
7713 [(set (match_operand:V4HI 0 "register_operand" "=e")
7714 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7715 (match_operand:V2HI 2 "register_operand" "f")))]
7717 "fmul8x16au\t%1, %2, %0"
7718 [(set_attr "type" "fpmul")
7719 (set_attr "fptype" "double")])
7721 (define_insn "fmul8x16al_vis"
7722 [(set (match_operand:V4HI 0 "register_operand" "=e")
7723 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
7724 (match_operand:V2HI 2 "register_operand" "f")]
7727 "fmul8x16al\t%1, %2, %0"
7728 [(set_attr "type" "fpmul")
7729 (set_attr "fptype" "double")])
7731 ;; Only one of the following two insns can be a multiply.
7732 (define_insn "fmul8sux16_vis"
7733 [(set (match_operand:V4HI 0 "register_operand" "=e")
7734 (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
7735 (match_operand:V4HI 2 "register_operand" "e")))]
7737 "fmul8sux16\t%1, %2, %0"
7738 [(set_attr "type" "fpmul")
7739 (set_attr "fptype" "double")])
7741 (define_insn "fmul8ulx16_vis"
7742 [(set (match_operand:V4HI 0 "register_operand" "=e")
7743 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
7744 (match_operand:V4HI 2 "register_operand" "e")]
7747 "fmul8ulx16\t%1, %2, %0"
7748 [(set_attr "type" "fpmul")
7749 (set_attr "fptype" "double")])
7751 ;; Only one of the following two insns can be a multiply.
7752 (define_insn "fmuld8sux16_vis"
7753 [(set (match_operand:V2SI 0 "register_operand" "=e")
7754 (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
7755 (match_operand:V2HI 2 "register_operand" "f")))]
7757 "fmuld8sux16\t%1, %2, %0"
7758 [(set_attr "type" "fpmul")
7759 (set_attr "fptype" "double")])
7761 (define_insn "fmuld8ulx16_vis"
7762 [(set (match_operand:V2SI 0 "register_operand" "=e")
7763 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
7764 (match_operand:V2HI 2 "register_operand" "f")]
7767 "fmuld8ulx16\t%1, %2, %0"
7768 [(set_attr "type" "fpmul")
7769 (set_attr "fptype" "double")])
7771 ;; Using faligndata only makes sense after an alignaddr since the choice of
7772 ;; bytes to take out of each operand is dependent on the results of the last
7774 (define_insn "faligndata<V64I:mode>_vis"
7775 [(set (match_operand:V64I 0 "register_operand" "=e")
7776 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
7777 (match_operand:V64I 2 "register_operand" "e")]
7780 "faligndata\t%1, %2, %0"
7781 [(set_attr "type" "fga")
7782 (set_attr "fptype" "double")])
7784 (define_insn "alignaddr<P:mode>_vis"
7785 [(set (match_operand:P 0 "register_operand" "=r")
7786 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
7787 (match_operand:P 2 "register_or_zero_operand" "rJ")]
7790 "alignaddr\t%r1, %r2, %0")
7792 (define_insn "pdist_vis"
7793 [(set (match_operand:DI 0 "register_operand" "=e")
7794 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
7795 (match_operand:V8QI 2 "register_operand" "e")
7796 (match_operand:DI 3 "register_operand" "0")]
7800 [(set_attr "type" "fga")
7801 (set_attr "fptype" "double")])