1 ;; Machine description for SPARC chip for GCC
2 ;; Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;; 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
4 ;; 2011 Free Software Foundation, Inc.
5 ;; Contributed by Michael Tiemann (tiemann@cygnus.com)
6 ;; 64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
9 ;; This file is part of GCC.
11 ;; GCC is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 3, or (at your option)
16 ;; GCC is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ;; GNU General Public License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GCC; see the file COPYING3. If not see
23 ;; <http://www.gnu.org/licenses/>.
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 (UNSPEC_UPDATE_RETURN 1)
30 (UNSPEC_LOAD_PCREL_SYM 2)
31 (UNSPEC_MOVE_PIC_LABEL 5)
37 (UNSPEC_EMB_TEXTUHI 13)
38 (UNSPEC_EMB_TEXTHI 14)
39 (UNSPEC_EMB_TEXTULO 15)
41 (UNSPEC_MOVE_GOTDATA 19)
50 (UNSPEC_TLSLD_BASE 35)
77 (UNSPECV_PROBE_STACK_RANGE 11)
81 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
82 (define_mode_iterator I [QI HI SI DI])
83 (define_mode_iterator F [SF DF TF])
85 ;; We don't define V1SI because SI should work just fine.
86 (define_mode_iterator V32 [SF V2HI V4QI])
87 (define_mode_iterator V32I [SI V2HI V4QI])
89 (define_mode_iterator V64 [DF V2SI V4HI V8QI])
90 (define_mode_iterator V64I [DI V2SI V4HI V8QI])
92 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
93 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
94 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
95 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
96 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
99 ;; Attribute for cpu type.
100 ;; These must match the values for enum processor_type in sparc.h.
119 (const (symbol_ref "sparc_cpu_attr")))
121 ;; Attribute for the instruction set.
122 ;; At present we only need to distinguish v9/!v9, but for clarity we
123 ;; test TARGET_V8 too.
124 (define_attr "isa" "v7,v8,v9,sparclet"
126 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
127 (symbol_ref "TARGET_V8") (const_string "v8")
128 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
129 (const_string "v7"))))
135 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
143 fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,
146 multi,savew,flushw,iflush,trap"
147 (const_string "ialu"))
149 ;; True if branch/call has empty delay slot and will emit a nop in it
150 (define_attr "empty_delay_slot" "false,true"
151 (symbol_ref "(empty_delay_slot (insn)
152 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
154 (define_attr "branch_type" "none,icc,fcc,reg"
155 (const_string "none"))
157 (define_attr "pic" "false,true"
158 (symbol_ref "(flag_pic != 0 ? PIC_TRUE : PIC_FALSE)"))
160 (define_attr "calls_alloca" "false,true"
161 (symbol_ref "(cfun->calls_alloca != 0
162 ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)"))
164 (define_attr "calls_eh_return" "false,true"
165 (symbol_ref "(crtl->calls_eh_return != 0
166 ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)"))
168 (define_attr "leaf_function" "false,true"
169 (symbol_ref "(current_function_uses_only_leaf_regs != 0
170 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
172 (define_attr "delayed_branch" "false,true"
173 (symbol_ref "(flag_delayed_branch != 0
174 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
176 ;; Length (in # of insns).
177 ;; Beware that setting a length greater or equal to 3 for conditional branches
178 ;; has a side-effect (see output_cbranch and output_v9branch).
179 (define_attr "length" ""
180 (cond [(eq_attr "type" "uncond_branch,call")
181 (if_then_else (eq_attr "empty_delay_slot" "true")
184 (eq_attr "type" "sibcall")
185 (if_then_else (eq_attr "leaf_function" "true")
186 (if_then_else (eq_attr "empty_delay_slot" "true")
189 (if_then_else (eq_attr "empty_delay_slot" "true")
192 (eq_attr "branch_type" "icc")
193 (if_then_else (match_operand 0 "noov_compare64_operator" "")
194 (if_then_else (lt (pc) (match_dup 1))
195 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
196 (if_then_else (eq_attr "empty_delay_slot" "true")
199 (if_then_else (eq_attr "empty_delay_slot" "true")
202 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
203 (if_then_else (eq_attr "empty_delay_slot" "true")
206 (if_then_else (eq_attr "empty_delay_slot" "true")
209 (if_then_else (eq_attr "empty_delay_slot" "true")
212 (eq_attr "branch_type" "fcc")
213 (if_then_else (match_operand 0 "fcc0_register_operand" "")
214 (if_then_else (eq_attr "empty_delay_slot" "true")
215 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
218 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
221 (if_then_else (lt (pc) (match_dup 2))
222 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
223 (if_then_else (eq_attr "empty_delay_slot" "true")
226 (if_then_else (eq_attr "empty_delay_slot" "true")
229 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
230 (if_then_else (eq_attr "empty_delay_slot" "true")
233 (if_then_else (eq_attr "empty_delay_slot" "true")
236 (eq_attr "branch_type" "reg")
237 (if_then_else (lt (pc) (match_dup 2))
238 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
239 (if_then_else (eq_attr "empty_delay_slot" "true")
242 (if_then_else (eq_attr "empty_delay_slot" "true")
245 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
246 (if_then_else (eq_attr "empty_delay_slot" "true")
249 (if_then_else (eq_attr "empty_delay_slot" "true")
255 (define_attr "fptype" "single,double"
256 (const_string "single"))
258 ;; UltraSPARC-III integer load type.
259 (define_attr "us3load_type" "2cycle,3cycle"
260 (const_string "2cycle"))
262 (define_asm_attributes
263 [(set_attr "length" "2")
264 (set_attr "type" "multi")])
266 ;; Attributes for instruction and branch scheduling
267 (define_attr "tls_call_delay" "false,true"
268 (symbol_ref "(tls_call_delay (insn)
269 ? TLS_CALL_DELAY_TRUE : TLS_CALL_DELAY_FALSE)"))
271 (define_attr "in_call_delay" "false,true"
272 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
273 (const_string "false")
274 (eq_attr "type" "load,fpload,store,fpstore")
275 (if_then_else (eq_attr "length" "1")
276 (const_string "true")
277 (const_string "false"))]
278 (if_then_else (and (eq_attr "length" "1")
279 (eq_attr "tls_call_delay" "true"))
280 (const_string "true")
281 (const_string "false"))))
283 (define_attr "eligible_for_sibcall_delay" "false,true"
284 (symbol_ref "(eligible_for_sibcall_delay (insn)
285 ? ELIGIBLE_FOR_SIBCALL_DELAY_TRUE
286 : ELIGIBLE_FOR_SIBCALL_DELAY_FALSE)"))
288 (define_attr "eligible_for_return_delay" "false,true"
289 (symbol_ref "(eligible_for_return_delay (insn)
290 ? ELIGIBLE_FOR_RETURN_DELAY_TRUE
291 : ELIGIBLE_FOR_RETURN_DELAY_FALSE)"))
293 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
294 ;; branches. This would allow us to remove the nop always inserted before
295 ;; a floating point branch.
297 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
298 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
299 ;; This is because doing so will add several pipeline stalls to the path
300 ;; that the load/store did not come from. Unfortunately, there is no way
301 ;; to prevent fill_eager_delay_slots from using load/store without completely
302 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
303 ;; because it prevents us from moving back the final store of inner loops.
305 (define_attr "in_branch_delay" "false,true"
306 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
307 (eq_attr "length" "1"))
308 (const_string "true")
309 (const_string "false")))
311 (define_attr "in_uncond_branch_delay" "false,true"
312 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
313 (eq_attr "length" "1"))
314 (const_string "true")
315 (const_string "false")))
317 (define_attr "in_annul_branch_delay" "false,true"
318 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
319 (eq_attr "length" "1"))
320 (const_string "true")
321 (const_string "false")))
323 (define_delay (eq_attr "type" "call")
324 [(eq_attr "in_call_delay" "true") (nil) (nil)])
326 (define_delay (eq_attr "type" "sibcall")
327 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
329 (define_delay (eq_attr "type" "branch")
330 [(eq_attr "in_branch_delay" "true")
331 (nil) (eq_attr "in_annul_branch_delay" "true")])
333 (define_delay (eq_attr "type" "uncond_branch")
334 [(eq_attr "in_uncond_branch_delay" "true")
337 (define_delay (eq_attr "type" "return")
338 [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
341 ;; Include SPARC DFA schedulers
343 (include "cypress.md")
344 (include "supersparc.md")
345 (include "hypersparc.md")
347 (include "sparclet.md")
348 (include "ultra1_2.md")
349 (include "ultra3.md")
350 (include "niagara.md")
351 (include "niagara2.md")
354 ;; Operand and operator predicates and constraints
356 (include "predicates.md")
357 (include "constraints.md")
360 ;; Compare instructions.
362 ;; These are just the DEFINE_INSNs to match the patterns and the
363 ;; DEFINE_SPLITs for some of the scc insns that actually require
364 ;; more than one machine instruction. DEFINE_EXPANDs are further down.
366 ;; The compare DEFINE_INSNs.
368 (define_insn "*cmpsi_insn"
370 (compare:CC (match_operand:SI 0 "register_operand" "r")
371 (match_operand:SI 1 "arith_operand" "rI")))]
374 [(set_attr "type" "compare")])
376 (define_insn "*cmpdi_sp64"
378 (compare:CCX (match_operand:DI 0 "register_operand" "r")
379 (match_operand:DI 1 "arith_operand" "rI")))]
382 [(set_attr "type" "compare")])
384 (define_insn "*cmpsf_fpe"
385 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
386 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
387 (match_operand:SF 2 "register_operand" "f")))]
391 return "fcmpes\t%0, %1, %2";
392 return "fcmpes\t%1, %2";
394 [(set_attr "type" "fpcmp")])
396 (define_insn "*cmpdf_fpe"
397 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
398 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
399 (match_operand:DF 2 "register_operand" "e")))]
403 return "fcmped\t%0, %1, %2";
404 return "fcmped\t%1, %2";
406 [(set_attr "type" "fpcmp")
407 (set_attr "fptype" "double")])
409 (define_insn "*cmptf_fpe"
410 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
411 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
412 (match_operand:TF 2 "register_operand" "e")))]
413 "TARGET_FPU && TARGET_HARD_QUAD"
416 return "fcmpeq\t%0, %1, %2";
417 return "fcmpeq\t%1, %2";
419 [(set_attr "type" "fpcmp")])
421 (define_insn "*cmpsf_fp"
422 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
423 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
424 (match_operand:SF 2 "register_operand" "f")))]
428 return "fcmps\t%0, %1, %2";
429 return "fcmps\t%1, %2";
431 [(set_attr "type" "fpcmp")])
433 (define_insn "*cmpdf_fp"
434 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
435 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
436 (match_operand:DF 2 "register_operand" "e")))]
440 return "fcmpd\t%0, %1, %2";
441 return "fcmpd\t%1, %2";
443 [(set_attr "type" "fpcmp")
444 (set_attr "fptype" "double")])
446 (define_insn "*cmptf_fp"
447 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
448 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
449 (match_operand:TF 2 "register_operand" "e")))]
450 "TARGET_FPU && TARGET_HARD_QUAD"
453 return "fcmpq\t%0, %1, %2";
454 return "fcmpq\t%1, %2";
456 [(set_attr "type" "fpcmp")])
458 ;; Next come the scc insns.
460 (define_expand "cstoresi4"
461 [(use (match_operator 1 "comparison_operator"
462 [(match_operand:SI 2 "compare_operand" "")
463 (match_operand:SI 3 "arith_operand" "")]))
464 (clobber (match_operand:SI 0 "register_operand"))]
467 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
468 operands[2] = force_reg (SImode, operands[2]);
469 if (emit_scc_insn (operands)) DONE; else FAIL;
472 (define_expand "cstoredi4"
473 [(use (match_operator 1 "comparison_operator"
474 [(match_operand:DI 2 "compare_operand" "")
475 (match_operand:DI 3 "arith_operand" "")]))
476 (clobber (match_operand:SI 0 "register_operand"))]
479 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
480 operands[2] = force_reg (DImode, operands[2]);
481 if (emit_scc_insn (operands)) DONE; else FAIL;
484 (define_expand "cstore<F:mode>4"
485 [(use (match_operator 1 "comparison_operator"
486 [(match_operand:F 2 "register_operand" "")
487 (match_operand:F 3 "register_operand" "")]))
488 (clobber (match_operand:SI 0 "register_operand"))]
490 { if (emit_scc_insn (operands)) DONE; else FAIL; })
494 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
495 ;; generate addcc/subcc instructions.
497 (define_expand "seqsi_special"
499 (xor:SI (match_operand:SI 1 "register_operand" "")
500 (match_operand:SI 2 "register_operand" "")))
501 (parallel [(set (match_operand:SI 0 "register_operand" "")
502 (eq:SI (match_dup 3) (const_int 0)))
503 (clobber (reg:CC 100))])]
505 { operands[3] = gen_reg_rtx (SImode); })
507 (define_expand "seqdi_special"
509 (xor:DI (match_operand:DI 1 "register_operand" "")
510 (match_operand:DI 2 "register_operand" "")))
511 (set (match_operand:SI 0 "register_operand" "")
512 (eq:SI (match_dup 3) (const_int 0)))]
514 { operands[3] = gen_reg_rtx (DImode); })
516 (define_expand "snesi_special"
518 (xor:SI (match_operand:SI 1 "register_operand" "")
519 (match_operand:SI 2 "register_operand" "")))
520 (parallel [(set (match_operand:SI 0 "register_operand" "")
521 (ne:SI (match_dup 3) (const_int 0)))
522 (clobber (reg:CC 100))])]
524 { operands[3] = gen_reg_rtx (SImode); })
526 (define_expand "snedi_special"
528 (xor:DI (match_operand:DI 1 "register_operand" "")
529 (match_operand:DI 2 "register_operand" "")))
530 (set (match_operand:SI 0 "register_operand" "")
531 (ne:SI (match_dup 3) (const_int 0)))]
533 { operands[3] = gen_reg_rtx (DImode); })
536 ;; Now the DEFINE_INSNs for the scc cases.
538 ;; The SEQ and SNE patterns are special because they can be done
539 ;; without any branching and do not involve a COMPARE. We want
540 ;; them to always use the splits below so the results can be
543 (define_insn_and_split "*snesi_zero"
544 [(set (match_operand:SI 0 "register_operand" "=r")
545 (ne:SI (match_operand:SI 1 "register_operand" "r")
547 (clobber (reg:CC 100))]
551 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
553 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
555 [(set_attr "length" "2")])
557 (define_insn_and_split "*neg_snesi_zero"
558 [(set (match_operand:SI 0 "register_operand" "=r")
559 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
561 (clobber (reg:CC 100))]
565 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
567 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
569 [(set_attr "length" "2")])
571 (define_insn_and_split "*snesi_zero_extend"
572 [(set (match_operand:DI 0 "register_operand" "=r")
573 (ne:DI (match_operand:SI 1 "register_operand" "r")
575 (clobber (reg:CC 100))]
579 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
582 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
584 (ltu:SI (reg:CC_NOOV 100)
587 [(set_attr "length" "2")])
589 (define_insn_and_split "*snedi_zero"
590 [(set (match_operand:DI 0 "register_operand" "=&r")
591 (ne:DI (match_operand:DI 1 "register_operand" "r")
595 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
596 [(set (match_dup 0) (const_int 0))
597 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
602 [(set_attr "length" "2")])
604 (define_insn_and_split "*neg_snedi_zero"
605 [(set (match_operand:DI 0 "register_operand" "=&r")
606 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
610 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
611 [(set (match_dup 0) (const_int 0))
612 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
617 [(set_attr "length" "2")])
619 (define_insn_and_split "*snedi_zero_trunc"
620 [(set (match_operand:SI 0 "register_operand" "=&r")
621 (ne:SI (match_operand:DI 1 "register_operand" "r")
625 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
626 [(set (match_dup 0) (const_int 0))
627 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
632 [(set_attr "length" "2")])
634 (define_insn_and_split "*seqsi_zero"
635 [(set (match_operand:SI 0 "register_operand" "=r")
636 (eq:SI (match_operand:SI 1 "register_operand" "r")
638 (clobber (reg:CC 100))]
642 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
644 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
646 [(set_attr "length" "2")])
648 (define_insn_and_split "*neg_seqsi_zero"
649 [(set (match_operand:SI 0 "register_operand" "=r")
650 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
652 (clobber (reg:CC 100))]
656 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
658 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
660 [(set_attr "length" "2")])
662 (define_insn_and_split "*seqsi_zero_extend"
663 [(set (match_operand:DI 0 "register_operand" "=r")
664 (eq:DI (match_operand:SI 1 "register_operand" "r")
666 (clobber (reg:CC 100))]
670 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
673 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
675 (ltu:SI (reg:CC_NOOV 100)
678 [(set_attr "length" "2")])
680 (define_insn_and_split "*seqdi_zero"
681 [(set (match_operand:DI 0 "register_operand" "=&r")
682 (eq:DI (match_operand:DI 1 "register_operand" "r")
686 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
687 [(set (match_dup 0) (const_int 0))
688 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
693 [(set_attr "length" "2")])
695 (define_insn_and_split "*neg_seqdi_zero"
696 [(set (match_operand:DI 0 "register_operand" "=&r")
697 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
701 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
702 [(set (match_dup 0) (const_int 0))
703 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
708 [(set_attr "length" "2")])
710 (define_insn_and_split "*seqdi_zero_trunc"
711 [(set (match_operand:SI 0 "register_operand" "=&r")
712 (eq:SI (match_operand:DI 1 "register_operand" "r")
716 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
717 [(set (match_dup 0) (const_int 0))
718 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
723 [(set_attr "length" "2")])
725 ;; We can also do (x + (i == 0)) and related, so put them in.
726 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
729 (define_insn_and_split "*x_plus_i_ne_0"
730 [(set (match_operand:SI 0 "register_operand" "=r")
731 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
733 (match_operand:SI 2 "register_operand" "r")))
734 (clobber (reg:CC 100))]
738 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
740 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
743 [(set_attr "length" "2")])
745 (define_insn_and_split "*x_minus_i_ne_0"
746 [(set (match_operand:SI 0 "register_operand" "=r")
747 (minus:SI (match_operand:SI 2 "register_operand" "r")
748 (ne:SI (match_operand:SI 1 "register_operand" "r")
750 (clobber (reg:CC 100))]
754 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
756 (set (match_dup 0) (minus:SI (match_dup 2)
757 (ltu:SI (reg:CC 100) (const_int 0))))]
759 [(set_attr "length" "2")])
761 (define_insn_and_split "*x_plus_i_eq_0"
762 [(set (match_operand:SI 0 "register_operand" "=r")
763 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
765 (match_operand:SI 2 "register_operand" "r")))
766 (clobber (reg:CC 100))]
770 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
772 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
775 [(set_attr "length" "2")])
777 (define_insn_and_split "*x_minus_i_eq_0"
778 [(set (match_operand:SI 0 "register_operand" "=r")
779 (minus:SI (match_operand:SI 2 "register_operand" "r")
780 (eq:SI (match_operand:SI 1 "register_operand" "r")
782 (clobber (reg:CC 100))]
786 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
788 (set (match_dup 0) (minus:SI (match_dup 2)
789 (geu:SI (reg:CC 100) (const_int 0))))]
791 [(set_attr "length" "2")])
793 ;; We can also do GEU and LTU directly, but these operate after a compare.
794 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
797 (define_insn "*sltu_insn"
798 [(set (match_operand:SI 0 "register_operand" "=r")
799 (ltu:SI (reg:CC 100) (const_int 0)))]
802 [(set_attr "type" "ialuX")])
804 (define_insn "*neg_sltu_insn"
805 [(set (match_operand:SI 0 "register_operand" "=r")
806 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
809 [(set_attr "type" "ialuX")])
811 ;; ??? Combine should canonicalize these next two to the same pattern.
812 (define_insn "*neg_sltu_minus_x"
813 [(set (match_operand:SI 0 "register_operand" "=r")
814 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
815 (match_operand:SI 1 "arith_operand" "rI")))]
818 [(set_attr "type" "ialuX")])
820 (define_insn "*neg_sltu_plus_x"
821 [(set (match_operand:SI 0 "register_operand" "=r")
822 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
823 (match_operand:SI 1 "arith_operand" "rI"))))]
826 [(set_attr "type" "ialuX")])
828 (define_insn "*sgeu_insn"
829 [(set (match_operand:SI 0 "register_operand" "=r")
830 (geu:SI (reg:CC 100) (const_int 0)))]
833 [(set_attr "type" "ialuX")])
835 (define_insn "*neg_sgeu_insn"
836 [(set (match_operand:SI 0 "register_operand" "=r")
837 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
840 [(set_attr "type" "ialuX")])
842 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
843 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
846 (define_insn "*sltu_plus_x"
847 [(set (match_operand:SI 0 "register_operand" "=r")
848 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
849 (match_operand:SI 1 "arith_operand" "rI")))]
852 [(set_attr "type" "ialuX")])
854 (define_insn "*sltu_plus_x_plus_y"
855 [(set (match_operand:SI 0 "register_operand" "=r")
856 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
857 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
858 (match_operand:SI 2 "arith_operand" "rI"))))]
861 [(set_attr "type" "ialuX")])
863 (define_insn "*x_minus_sltu"
864 [(set (match_operand:SI 0 "register_operand" "=r")
865 (minus:SI (match_operand:SI 1 "register_operand" "r")
866 (ltu:SI (reg:CC 100) (const_int 0))))]
869 [(set_attr "type" "ialuX")])
871 ;; ??? Combine should canonicalize these next two to the same pattern.
872 (define_insn "*x_minus_y_minus_sltu"
873 [(set (match_operand:SI 0 "register_operand" "=r")
874 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
875 (match_operand:SI 2 "arith_operand" "rI"))
876 (ltu:SI (reg:CC 100) (const_int 0))))]
879 [(set_attr "type" "ialuX")])
881 (define_insn "*x_minus_sltu_plus_y"
882 [(set (match_operand:SI 0 "register_operand" "=r")
883 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
884 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
885 (match_operand:SI 2 "arith_operand" "rI"))))]
888 [(set_attr "type" "ialuX")])
890 (define_insn "*sgeu_plus_x"
891 [(set (match_operand:SI 0 "register_operand" "=r")
892 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
893 (match_operand:SI 1 "register_operand" "r")))]
896 [(set_attr "type" "ialuX")])
898 (define_insn "*x_minus_sgeu"
899 [(set (match_operand:SI 0 "register_operand" "=r")
900 (minus:SI (match_operand:SI 1 "register_operand" "r")
901 (geu:SI (reg:CC 100) (const_int 0))))]
904 [(set_attr "type" "ialuX")])
907 [(set (match_operand:SI 0 "register_operand" "")
908 (match_operator:SI 2 "noov_compare_operator"
909 [(match_operand 1 "icc_or_fcc_register_operand" "")
912 && REGNO (operands[1]) == SPARC_ICC_REG
913 && (GET_MODE (operands[1]) == CCXmode
914 /* 32-bit LTU/GEU are better implemented using addx/subx. */
915 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
916 [(set (match_dup 0) (const_int 0))
918 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
924 ;; These control RTL generation for conditional jump insns
926 (define_expand "cbranchcc4"
928 (if_then_else (match_operator 0 "comparison_operator"
929 [(match_operand 1 "compare_operand" "")
930 (match_operand 2 "const_zero_operand" "")])
931 (label_ref (match_operand 3 "" ""))
936 (define_expand "cbranchsi4"
937 [(use (match_operator 0 "comparison_operator"
938 [(match_operand:SI 1 "compare_operand" "")
939 (match_operand:SI 2 "arith_operand" "")]))
940 (use (match_operand 3 ""))]
943 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
944 operands[1] = force_reg (SImode, operands[1]);
945 emit_conditional_branch_insn (operands);
949 (define_expand "cbranchdi4"
950 [(use (match_operator 0 "comparison_operator"
951 [(match_operand:DI 1 "compare_operand" "")
952 (match_operand:DI 2 "arith_operand" "")]))
953 (use (match_operand 3 ""))]
956 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
957 operands[1] = force_reg (DImode, operands[1]);
958 emit_conditional_branch_insn (operands);
962 (define_expand "cbranch<F:mode>4"
963 [(use (match_operator 0 "comparison_operator"
964 [(match_operand:F 1 "register_operand" "")
965 (match_operand:F 2 "register_operand" "")]))
966 (use (match_operand 3 ""))]
968 { emit_conditional_branch_insn (operands); DONE; })
971 ;; Now match both normal and inverted jump.
973 ;; XXX fpcmp nop braindamage
974 (define_insn "*normal_branch"
976 (if_then_else (match_operator 0 "noov_compare_operator"
977 [(reg 100) (const_int 0)])
978 (label_ref (match_operand 1 "" ""))
982 return output_cbranch (operands[0], operands[1], 1, 0,
983 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
986 [(set_attr "type" "branch")
987 (set_attr "branch_type" "icc")])
989 ;; XXX fpcmp nop braindamage
990 (define_insn "*inverted_branch"
992 (if_then_else (match_operator 0 "noov_compare_operator"
993 [(reg 100) (const_int 0)])
995 (label_ref (match_operand 1 "" ""))))]
998 return output_cbranch (operands[0], operands[1], 1, 1,
999 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1002 [(set_attr "type" "branch")
1003 (set_attr "branch_type" "icc")])
1005 ;; XXX fpcmp nop braindamage
1006 (define_insn "*normal_fp_branch"
1008 (if_then_else (match_operator 1 "comparison_operator"
1009 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1011 (label_ref (match_operand 2 "" ""))
1015 return output_cbranch (operands[1], operands[2], 2, 0,
1016 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1019 [(set_attr "type" "branch")
1020 (set_attr "branch_type" "fcc")])
1022 ;; XXX fpcmp nop braindamage
1023 (define_insn "*inverted_fp_branch"
1025 (if_then_else (match_operator 1 "comparison_operator"
1026 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1029 (label_ref (match_operand 2 "" ""))))]
1032 return output_cbranch (operands[1], operands[2], 2, 1,
1033 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1036 [(set_attr "type" "branch")
1037 (set_attr "branch_type" "fcc")])
1039 ;; XXX fpcmp nop braindamage
1040 (define_insn "*normal_fpe_branch"
1042 (if_then_else (match_operator 1 "comparison_operator"
1043 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1045 (label_ref (match_operand 2 "" ""))
1049 return output_cbranch (operands[1], operands[2], 2, 0,
1050 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1053 [(set_attr "type" "branch")
1054 (set_attr "branch_type" "fcc")])
1056 ;; XXX fpcmp nop braindamage
1057 (define_insn "*inverted_fpe_branch"
1059 (if_then_else (match_operator 1 "comparison_operator"
1060 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1063 (label_ref (match_operand 2 "" ""))))]
1066 return output_cbranch (operands[1], operands[2], 2, 1,
1067 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1070 [(set_attr "type" "branch")
1071 (set_attr "branch_type" "fcc")])
1073 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1074 ;; in the architecture.
1076 ;; There are no 32 bit brreg insns.
1079 (define_insn "*normal_int_branch_sp64"
1081 (if_then_else (match_operator 0 "v9_register_compare_operator"
1082 [(match_operand:DI 1 "register_operand" "r")
1084 (label_ref (match_operand 2 "" ""))
1088 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1089 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1092 [(set_attr "type" "branch")
1093 (set_attr "branch_type" "reg")])
1096 (define_insn "*inverted_int_branch_sp64"
1098 (if_then_else (match_operator 0 "v9_register_compare_operator"
1099 [(match_operand:DI 1 "register_operand" "r")
1102 (label_ref (match_operand 2 "" ""))))]
1105 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1106 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1109 [(set_attr "type" "branch")
1110 (set_attr "branch_type" "reg")])
1113 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1114 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1115 ;; that adds the PC value at the call point to register #(operand 3).
1117 (define_insn "load_pcrel_sym<P:mode>"
1118 [(set (match_operand:P 0 "register_operand" "=r")
1119 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1120 (match_operand:P 2 "call_address_operand" "")
1121 (match_operand:P 3 "const_int_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1122 (clobber (reg:P 15))]
1123 "REGNO (operands[0]) == INTVAL (operands[3])"
1125 if (flag_delayed_branch)
1126 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1128 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1130 [(set (attr "type") (const_string "multi"))
1131 (set (attr "length")
1132 (if_then_else (eq_attr "delayed_branch" "true")
1137 ;; Integer move instructions
1139 (define_expand "movqi"
1140 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1141 (match_operand:QI 1 "general_operand" ""))]
1144 if (sparc_expand_move (QImode, operands))
1148 (define_insn "*movqi_insn"
1149 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1150 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1151 "(register_operand (operands[0], QImode)
1152 || register_or_zero_operand (operands[1], QImode))"
1157 [(set_attr "type" "*,load,store")
1158 (set_attr "us3load_type" "*,3cycle,*")])
1160 (define_expand "movhi"
1161 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1162 (match_operand:HI 1 "general_operand" ""))]
1165 if (sparc_expand_move (HImode, operands))
1169 (define_insn "*movhi_insn"
1170 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1171 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1172 "(register_operand (operands[0], HImode)
1173 || register_or_zero_operand (operands[1], HImode))"
1176 sethi\t%%hi(%a1), %0
1179 [(set_attr "type" "*,*,load,store")
1180 (set_attr "us3load_type" "*,*,3cycle,*")])
1182 ;; We always work with constants here.
1183 (define_insn "*movhi_lo_sum"
1184 [(set (match_operand:HI 0 "register_operand" "=r")
1185 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1186 (match_operand:HI 2 "small_int_operand" "I")))]
1190 (define_expand "movsi"
1191 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1192 (match_operand:SI 1 "general_operand" ""))]
1195 if (sparc_expand_move (SImode, operands))
1199 (define_insn "*movsi_insn"
1200 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d")
1201 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,f,m,f,J"))]
1202 "(register_operand (operands[0], SImode)
1203 || register_or_zero_operand (operands[1], SImode))"
1206 sethi\t%%hi(%a1), %0
1213 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")])
1215 (define_insn "*movsi_lo_sum"
1216 [(set (match_operand:SI 0 "register_operand" "=r")
1217 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1218 (match_operand:SI 2 "immediate_operand" "in")))]
1220 "or\t%1, %%lo(%a2), %0")
1222 (define_insn "*movsi_high"
1223 [(set (match_operand:SI 0 "register_operand" "=r")
1224 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1226 "sethi\t%%hi(%a1), %0")
1228 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1229 ;; so that CSE won't optimize the address computation away.
1230 (define_insn "movsi_lo_sum_pic"
1231 [(set (match_operand:SI 0 "register_operand" "=r")
1232 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1233 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1236 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1237 return "xor\t%1, %%gdop_lox10(%a2), %0";
1239 return "or\t%1, %%lo(%a2), %0";
1243 (define_insn "movsi_high_pic"
1244 [(set (match_operand:SI 0 "register_operand" "=r")
1245 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1246 "flag_pic && check_pic (1)"
1248 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1249 return "sethi\t%%gdop_hix22(%a1), %0";
1251 return "sethi\t%%hi(%a1), %0";
1255 (define_insn "movsi_pic_gotdata_op"
1256 [(set (match_operand:SI 0 "register_operand" "=r")
1257 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1258 (match_operand:SI 2 "register_operand" "r")
1259 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1260 "flag_pic && check_pic (1)"
1262 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1263 return "ld\t[%1 + %2], %0, %%gdop(%a3)";
1265 return "ld\t[%1 + %2], %0";
1268 [(set_attr "type" "load")])
1270 (define_expand "movsi_pic_label_ref"
1271 [(set (match_dup 3) (high:SI
1272 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1273 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1274 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1275 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1276 (set (match_operand:SI 0 "register_operand" "=r")
1277 (minus:SI (match_dup 5) (match_dup 4)))]
1280 crtl->uses_pic_offset_table = 1;
1281 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1282 if (!can_create_pseudo_p ())
1284 operands[3] = operands[0];
1285 operands[4] = operands[0];
1289 operands[3] = gen_reg_rtx (SImode);
1290 operands[4] = gen_reg_rtx (SImode);
1292 operands[5] = pic_offset_table_rtx;
1295 (define_insn "*movsi_high_pic_label_ref"
1296 [(set (match_operand:SI 0 "register_operand" "=r")
1298 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1299 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1301 "sethi\t%%hi(%a2-(%a1-.)), %0")
1303 (define_insn "*movsi_lo_sum_pic_label_ref"
1304 [(set (match_operand:SI 0 "register_operand" "=r")
1305 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1306 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1307 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1309 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1311 ;; Set up the PIC register for VxWorks.
1313 (define_expand "vxworks_load_got"
1315 (high:SI (match_dup 1)))
1317 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1319 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1320 "TARGET_VXWORKS_RTP"
1322 operands[0] = pic_offset_table_rtx;
1323 operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1324 operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1327 (define_expand "movdi"
1328 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1329 (match_operand:DI 1 "general_operand" ""))]
1332 if (sparc_expand_move (DImode, operands))
1336 ;; Be careful, fmovd does not exist when !v9.
1337 ;; We match MEM moves directly when we have correct even
1338 ;; numbered registers, but fall into splits otherwise.
1339 ;; The constraint ordering here is really important to
1340 ;; avoid insane problems in reload, especially for patterns
1343 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1344 ;; (const_int -5016)))
1348 (define_insn "*movdi_insn_sp32"
1349 [(set (match_operand:DI 0 "nonimmediate_operand"
1350 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1351 (match_operand:DI 1 "input_operand"
1352 " J,U,T,r,o,i,r, f, T, o, f, f"))]
1354 && (register_operand (operands[0], DImode)
1355 || register_or_zero_operand (operands[1], DImode))"
1369 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1370 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1372 (define_insn "*movdi_insn_sp32_v9"
1373 [(set (match_operand:DI 0 "nonimmediate_operand"
1374 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1375 (match_operand:DI 1 "input_operand"
1376 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1379 && (register_operand (operands[0], DImode)
1380 || register_or_zero_operand (operands[1], DImode))"
1397 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
1398 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
1399 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
1401 (define_insn "*movdi_insn_sp64"
1402 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b")
1403 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,e,W,e,J"))]
1405 && (register_operand (operands[0], DImode)
1406 || register_or_zero_operand (operands[1], DImode))"
1409 sethi\t%%hi(%a1), %0
1416 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")
1417 (set_attr "fptype" "*,*,*,*,double,*,*,double")])
1419 (define_expand "movdi_pic_label_ref"
1420 [(set (match_dup 3) (high:DI
1421 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1422 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1423 (set (match_dup 4) (lo_sum:DI (match_dup 3)
1424 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1425 (set (match_operand:DI 0 "register_operand" "=r")
1426 (minus:DI (match_dup 5) (match_dup 4)))]
1427 "TARGET_ARCH64 && flag_pic"
1429 crtl->uses_pic_offset_table = 1;
1430 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1431 if (!can_create_pseudo_p ())
1433 operands[3] = operands[0];
1434 operands[4] = operands[0];
1438 operands[3] = gen_reg_rtx (DImode);
1439 operands[4] = gen_reg_rtx (DImode);
1441 operands[5] = pic_offset_table_rtx;
1444 (define_insn "*movdi_high_pic_label_ref"
1445 [(set (match_operand:DI 0 "register_operand" "=r")
1447 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1448 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1449 "TARGET_ARCH64 && flag_pic"
1450 "sethi\t%%hi(%a2-(%a1-.)), %0")
1452 (define_insn "*movdi_lo_sum_pic_label_ref"
1453 [(set (match_operand:DI 0 "register_operand" "=r")
1454 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1455 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
1456 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1457 "TARGET_ARCH64 && flag_pic"
1458 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1460 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
1461 ;; in sparc.c to see what is going on here... PIC stuff comes first.
1463 (define_insn "movdi_lo_sum_pic"
1464 [(set (match_operand:DI 0 "register_operand" "=r")
1465 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1466 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1467 "TARGET_ARCH64 && flag_pic"
1469 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1470 return "xor\t%1, %%gdop_lox10(%a2), %0";
1472 return "or\t%1, %%lo(%a2), %0";
1476 (define_insn "movdi_high_pic"
1477 [(set (match_operand:DI 0 "register_operand" "=r")
1478 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1479 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1481 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1482 return "sethi\t%%gdop_hix22(%a1), %0";
1484 return "sethi\t%%hi(%a1), %0";
1488 (define_insn "movdi_pic_gotdata_op"
1489 [(set (match_operand:DI 0 "register_operand" "=r")
1490 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1491 (match_operand:DI 2 "register_operand" "r")
1492 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1493 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1495 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1496 return "ldx\t[%1 + %2], %0, %%gdop(%a3)";
1498 return "ldx\t[%1 + %2], %0";
1501 [(set_attr "type" "load")])
1503 (define_insn "*sethi_di_medlow_embmedany_pic"
1504 [(set (match_operand:DI 0 "register_operand" "=r")
1505 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
1506 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
1507 "sethi\t%%hi(%a1), %0")
1509 (define_insn "*sethi_di_medlow"
1510 [(set (match_operand:DI 0 "register_operand" "=r")
1511 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
1512 "TARGET_CM_MEDLOW && check_pic (1)"
1513 "sethi\t%%hi(%a1), %0")
1515 (define_insn "*losum_di_medlow"
1516 [(set (match_operand:DI 0 "register_operand" "=r")
1517 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1518 (match_operand:DI 2 "symbolic_operand" "")))]
1520 "or\t%1, %%lo(%a2), %0")
1522 (define_insn "seth44"
1523 [(set (match_operand:DI 0 "register_operand" "=r")
1524 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
1526 "sethi\t%%h44(%a1), %0")
1528 (define_insn "setm44"
1529 [(set (match_operand:DI 0 "register_operand" "=r")
1530 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1531 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
1533 "or\t%1, %%m44(%a2), %0")
1535 (define_insn "setl44"
1536 [(set (match_operand:DI 0 "register_operand" "=r")
1537 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1538 (match_operand:DI 2 "symbolic_operand" "")))]
1540 "or\t%1, %%l44(%a2), %0")
1542 (define_insn "sethh"
1543 [(set (match_operand:DI 0 "register_operand" "=r")
1544 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
1546 "sethi\t%%hh(%a1), %0")
1548 (define_insn "setlm"
1549 [(set (match_operand:DI 0 "register_operand" "=r")
1550 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
1552 "sethi\t%%lm(%a1), %0")
1554 (define_insn "sethm"
1555 [(set (match_operand:DI 0 "register_operand" "=r")
1556 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1557 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
1559 "or\t%1, %%hm(%a2), %0")
1561 (define_insn "setlo"
1562 [(set (match_operand:DI 0 "register_operand" "=r")
1563 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1564 (match_operand:DI 2 "symbolic_operand" "")))]
1566 "or\t%1, %%lo(%a2), %0")
1568 (define_insn "embmedany_sethi"
1569 [(set (match_operand:DI 0 "register_operand" "=r")
1570 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
1571 "TARGET_CM_EMBMEDANY && check_pic (1)"
1572 "sethi\t%%hi(%a1), %0")
1574 (define_insn "embmedany_losum"
1575 [(set (match_operand:DI 0 "register_operand" "=r")
1576 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1577 (match_operand:DI 2 "data_segment_operand" "")))]
1578 "TARGET_CM_EMBMEDANY"
1579 "add\t%1, %%lo(%a2), %0")
1581 (define_insn "embmedany_brsum"
1582 [(set (match_operand:DI 0 "register_operand" "=r")
1583 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
1584 "TARGET_CM_EMBMEDANY"
1587 (define_insn "embmedany_textuhi"
1588 [(set (match_operand:DI 0 "register_operand" "=r")
1589 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
1590 "TARGET_CM_EMBMEDANY && check_pic (1)"
1591 "sethi\t%%uhi(%a1), %0")
1593 (define_insn "embmedany_texthi"
1594 [(set (match_operand:DI 0 "register_operand" "=r")
1595 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
1596 "TARGET_CM_EMBMEDANY && check_pic (1)"
1597 "sethi\t%%hi(%a1), %0")
1599 (define_insn "embmedany_textulo"
1600 [(set (match_operand:DI 0 "register_operand" "=r")
1601 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1602 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
1603 "TARGET_CM_EMBMEDANY"
1604 "or\t%1, %%ulo(%a2), %0")
1606 (define_insn "embmedany_textlo"
1607 [(set (match_operand:DI 0 "register_operand" "=r")
1608 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1609 (match_operand:DI 2 "text_segment_operand" "")))]
1610 "TARGET_CM_EMBMEDANY"
1611 "or\t%1, %%lo(%a2), %0")
1613 ;; Now some patterns to help reload out a bit.
1614 (define_expand "reload_indi"
1615 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1616 (match_operand:DI 1 "immediate_operand" "")
1617 (match_operand:TI 2 "register_operand" "=&r")])]
1619 || TARGET_CM_EMBMEDANY)
1622 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1626 (define_expand "reload_outdi"
1627 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1628 (match_operand:DI 1 "immediate_operand" "")
1629 (match_operand:TI 2 "register_operand" "=&r")])]
1631 || TARGET_CM_EMBMEDANY)
1634 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1638 ;; Split up putting CONSTs and REGs into DI regs when !arch64
1640 [(set (match_operand:DI 0 "register_operand" "")
1641 (match_operand:DI 1 "const_int_operand" ""))]
1642 "! TARGET_ARCH64 && reload_completed"
1643 [(clobber (const_int 0))]
1645 #if HOST_BITS_PER_WIDE_INT == 32
1646 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1647 (INTVAL (operands[1]) < 0) ?
1650 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1653 unsigned int low, high;
1655 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
1656 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
1657 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
1659 /* Slick... but this trick loses if this subreg constant part
1660 can be done in one insn. */
1662 && ! SPARC_SETHI32_P (high)
1663 && ! SPARC_SIMM13_P (high))
1664 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1665 gen_highpart (SImode, operands[0])));
1667 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
1673 [(set (match_operand:DI 0 "register_operand" "")
1674 (match_operand:DI 1 "const_double_operand" ""))]
1678 && ((GET_CODE (operands[0]) == REG
1679 && REGNO (operands[0]) < 32)
1680 || (GET_CODE (operands[0]) == SUBREG
1681 && GET_CODE (SUBREG_REG (operands[0])) == REG
1682 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1683 [(clobber (const_int 0))]
1685 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1686 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
1688 /* Slick... but this trick loses if this subreg constant part
1689 can be done in one insn. */
1690 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
1691 && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
1692 && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
1694 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1695 gen_highpart (SImode, operands[0])));
1699 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1700 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
1706 [(set (match_operand:DI 0 "register_operand" "")
1707 (match_operand:DI 1 "register_operand" ""))]
1711 && ((GET_CODE (operands[0]) == REG
1712 && REGNO (operands[0]) < 32)
1713 || (GET_CODE (operands[0]) == SUBREG
1714 && GET_CODE (SUBREG_REG (operands[0])) == REG
1715 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1716 [(clobber (const_int 0))]
1718 rtx set_dest = operands[0];
1719 rtx set_src = operands[1];
1723 dest1 = gen_highpart (SImode, set_dest);
1724 dest2 = gen_lowpart (SImode, set_dest);
1725 src1 = gen_highpart (SImode, set_src);
1726 src2 = gen_lowpart (SImode, set_src);
1728 /* Now emit using the real source and destination we found, swapping
1729 the order if we detect overlap. */
1730 if (reg_overlap_mentioned_p (dest1, src2))
1732 emit_insn (gen_movsi (dest2, src2));
1733 emit_insn (gen_movsi (dest1, src1));
1737 emit_insn (gen_movsi (dest1, src1));
1738 emit_insn (gen_movsi (dest2, src2));
1743 ;; Now handle the cases of memory moves from/to non-even
1744 ;; DI mode register pairs.
1746 [(set (match_operand:DI 0 "register_operand" "")
1747 (match_operand:DI 1 "memory_operand" ""))]
1750 && sparc_splitdi_legitimate (operands[0], operands[1]))"
1751 [(clobber (const_int 0))]
1753 rtx word0 = adjust_address (operands[1], SImode, 0);
1754 rtx word1 = adjust_address (operands[1], SImode, 4);
1755 rtx high_part = gen_highpart (SImode, operands[0]);
1756 rtx low_part = gen_lowpart (SImode, operands[0]);
1758 if (reg_overlap_mentioned_p (high_part, word1))
1760 emit_insn (gen_movsi (low_part, word1));
1761 emit_insn (gen_movsi (high_part, word0));
1765 emit_insn (gen_movsi (high_part, word0));
1766 emit_insn (gen_movsi (low_part, word1));
1772 [(set (match_operand:DI 0 "memory_operand" "")
1773 (match_operand:DI 1 "register_operand" ""))]
1776 && sparc_splitdi_legitimate (operands[1], operands[0]))"
1777 [(clobber (const_int 0))]
1779 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
1780 gen_highpart (SImode, operands[1])));
1781 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
1782 gen_lowpart (SImode, operands[1])));
1787 [(set (match_operand:DI 0 "memory_operand" "")
1788 (match_operand:DI 1 "const_zero_operand" ""))]
1792 && ! mem_min_alignment (operands[0], 8)))
1793 && offsettable_memref_p (operands[0])"
1794 [(clobber (const_int 0))]
1796 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
1797 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
1802 ;; Floating point and vector move instructions
1804 ;; Yes, you guessed it right, the former movsf expander.
1805 (define_expand "mov<V32:mode>"
1806 [(set (match_operand:V32 0 "nonimmediate_operand" "")
1807 (match_operand:V32 1 "general_operand" ""))]
1808 "<V32:MODE>mode == SFmode || TARGET_VIS"
1810 if (sparc_expand_move (<V32:MODE>mode, operands))
1814 (define_insn "*movsf_insn"
1815 [(set (match_operand:V32 0 "nonimmediate_operand" "=d,f,*r,*r,*r,f,*r,m,m")
1816 (match_operand:V32 1 "input_operand" "GY,f,*rRY,Q,S,m,m,f,*rGY"))]
1818 && (register_operand (operands[0], <V32:MODE>mode)
1819 || register_or_zero_operand (operands[1], <V32:MODE>mode))"
1821 if (GET_CODE (operands[1]) == CONST_DOUBLE
1822 && (which_alternative == 2
1823 || which_alternative == 3
1824 || which_alternative == 4))
1829 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1830 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1831 operands[1] = GEN_INT (i);
1834 switch (which_alternative)
1837 return "fzeros\t%0";
1839 return "fmovs\t%1, %0";
1841 return "mov\t%1, %0";
1843 return "sethi\t%%hi(%a1), %0";
1848 return "ld\t%1, %0";
1851 return "st\t%r1, %0";
1856 [(set_attr "type" "fga,fpmove,*,*,*,fpload,load,fpstore,store")])
1858 ;; Exactly the same as above, except that all `f' cases are deleted.
1859 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1862 (define_insn "*movsf_insn_no_fpu"
1863 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
1864 (match_operand:SF 1 "input_operand" "rR,Q,S,m,rG"))]
1866 && (register_operand (operands[0], SFmode)
1867 || register_or_zero_operand (operands[1], SFmode))"
1869 if (GET_CODE (operands[1]) == CONST_DOUBLE
1870 && (which_alternative == 0
1871 || which_alternative == 1
1872 || which_alternative == 2))
1877 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1878 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1879 operands[1] = GEN_INT (i);
1882 switch (which_alternative)
1885 return "mov\t%1, %0";
1887 return "sethi\t%%hi(%a1), %0";
1891 return "ld\t%1, %0";
1893 return "st\t%r1, %0";
1898 [(set_attr "type" "*,*,*,load,store")])
1900 ;; The following 3 patterns build SFmode constants in integer registers.
1902 (define_insn "*movsf_lo_sum"
1903 [(set (match_operand:SF 0 "register_operand" "=r")
1904 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
1905 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
1911 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
1912 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1913 operands[2] = GEN_INT (i);
1914 return "or\t%1, %%lo(%a2), %0";
1917 (define_insn "*movsf_high"
1918 [(set (match_operand:SF 0 "register_operand" "=r")
1919 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
1925 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1926 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1927 operands[1] = GEN_INT (i);
1928 return "sethi\t%%hi(%1), %0";
1932 [(set (match_operand:SF 0 "register_operand" "")
1933 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
1934 "REG_P (operands[0]) && REGNO (operands[0]) < 32"
1935 [(set (match_dup 0) (high:SF (match_dup 1)))
1936 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
1938 ;; Yes, you again guessed it right, the former movdf expander.
1939 (define_expand "mov<V64:mode>"
1940 [(set (match_operand:V64 0 "nonimmediate_operand" "")
1941 (match_operand:V64 1 "general_operand" ""))]
1942 "<V64:MODE>mode == DFmode || TARGET_VIS"
1944 if (sparc_expand_move (<V64:MODE>mode, operands))
1948 ;; Be careful, fmovd does not exist when !v9.
1949 (define_insn "*movdf_insn_sp32"
1950 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
1951 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
1954 && (register_operand (operands[0], DFmode)
1955 || register_or_zero_operand (operands[1], DFmode))"
1967 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
1968 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
1970 (define_insn "*movdf_insn_sp32_no_fpu"
1971 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
1972 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
1975 && (register_operand (operands[0], DFmode)
1976 || register_or_zero_operand (operands[1], DFmode))"
1983 [(set_attr "type" "load,store,*,*,*")
1984 (set_attr "length" "*,*,2,2,2")])
1986 ;; We have available v9 double floats but not 64-bit integer registers.
1987 (define_insn "*movdf_insn_sp32_v9"
1988 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o")
1989 (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYDF,*rGYf"))]
1993 && (register_operand (operands[0], <V64:MODE>mode)
1994 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2006 [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
2007 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2008 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2010 (define_insn "*movdf_insn_sp32_v9_no_fpu"
2011 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2012 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2016 && (register_operand (operands[0], DFmode)
2017 || register_or_zero_operand (operands[1], DFmode))"
2024 [(set_attr "type" "load,store,store,*,*")
2025 (set_attr "length" "*,*,*,2,2")])
2027 ;; We have available both v9 double floats and 64-bit integer registers.
2028 (define_insn "*movdf_insn_sp64"
2029 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r")
2030 (match_operand:V64 1 "input_operand" "GY,e,W#F,e,*rGY,m,*rGY,DF"))]
2033 && (register_operand (operands[0], <V64:MODE>mode)
2034 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2044 [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
2045 (set_attr "length" "*,*,*,*,*,*,*,2")
2046 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
2048 (define_insn "*movdf_insn_sp64_no_fpu"
2049 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2050 (match_operand:DF 1 "input_operand" "r,m,rG"))]
2053 && (register_operand (operands[0], DFmode)
2054 || register_or_zero_operand (operands[1], DFmode))"
2059 [(set_attr "type" "*,load,store")])
2061 ;; This pattern builds V64mode constants in integer registers.
2063 [(set (match_operand:V64 0 "register_operand" "")
2064 (match_operand:V64 1 "const_double_or_vector_operand" ""))]
2066 && (GET_CODE (operands[0]) == REG
2067 && REGNO (operands[0]) < 32)
2068 && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2069 && reload_completed"
2070 [(clobber (const_int 0))]
2072 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2076 #if HOST_BITS_PER_WIDE_INT == 32
2079 enum machine_mode mode = GET_MODE (operands[1]);
2080 rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2081 emit_insn (gen_movdi (operands[0], tem));
2086 enum machine_mode mode = GET_MODE (operands[1]);
2087 rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2088 rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2090 gcc_assert (GET_CODE (hi) == CONST_INT);
2091 gcc_assert (GET_CODE (lo) == CONST_INT);
2093 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2095 /* Slick... but this trick loses if this subreg constant part
2096 can be done in one insn. */
2098 && ! SPARC_SETHI32_P (INTVAL (hi))
2099 && ! SPARC_SIMM13_P (INTVAL (hi)))
2101 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2102 gen_highpart (SImode, operands[0])));
2106 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2112 ;; Ok, now the splits to handle all the multi insn and
2113 ;; mis-aligned memory address cases.
2114 ;; In these splits please take note that we must be
2115 ;; careful when V9 but not ARCH64 because the integer
2116 ;; register DFmode cases must be handled.
2118 [(set (match_operand:V64 0 "register_operand" "")
2119 (match_operand:V64 1 "register_operand" ""))]
2122 && ((GET_CODE (operands[0]) == REG
2123 && REGNO (operands[0]) < 32)
2124 || (GET_CODE (operands[0]) == SUBREG
2125 && GET_CODE (SUBREG_REG (operands[0])) == REG
2126 && REGNO (SUBREG_REG (operands[0])) < 32))))
2127 && reload_completed"
2128 [(clobber (const_int 0))]
2130 rtx set_dest = operands[0];
2131 rtx set_src = operands[1];
2134 enum machine_mode half_mode;
2136 /* We can be expanded for DFmode or integral vector modes. */
2137 if (<V64:MODE>mode == DFmode)
2142 dest1 = gen_highpart (half_mode, set_dest);
2143 dest2 = gen_lowpart (half_mode, set_dest);
2144 src1 = gen_highpart (half_mode, set_src);
2145 src2 = gen_lowpart (half_mode, set_src);
2147 /* Now emit using the real source and destination we found, swapping
2148 the order if we detect overlap. */
2149 if (reg_overlap_mentioned_p (dest1, src2))
2151 emit_move_insn_1 (dest2, src2);
2152 emit_move_insn_1 (dest1, src1);
2156 emit_move_insn_1 (dest1, src1);
2157 emit_move_insn_1 (dest2, src2);
2163 [(set (match_operand:V64 0 "register_operand" "")
2164 (match_operand:V64 1 "memory_operand" ""))]
2167 && (((REGNO (operands[0]) % 2) != 0)
2168 || ! mem_min_alignment (operands[1], 8))
2169 && offsettable_memref_p (operands[1])"
2170 [(clobber (const_int 0))]
2172 enum machine_mode half_mode;
2175 /* We can be expanded for DFmode or integral vector modes. */
2176 if (<V64:MODE>mode == DFmode)
2181 word0 = adjust_address (operands[1], half_mode, 0);
2182 word1 = adjust_address (operands[1], half_mode, 4);
2184 if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
2186 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2187 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2191 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2192 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2198 [(set (match_operand:V64 0 "memory_operand" "")
2199 (match_operand:V64 1 "register_operand" ""))]
2202 && (((REGNO (operands[1]) % 2) != 0)
2203 || ! mem_min_alignment (operands[0], 8))
2204 && offsettable_memref_p (operands[0])"
2205 [(clobber (const_int 0))]
2207 enum machine_mode half_mode;
2210 /* We can be expanded for DFmode or integral vector modes. */
2211 if (<V64:MODE>mode == DFmode)
2216 word0 = adjust_address (operands[0], half_mode, 0);
2217 word1 = adjust_address (operands[0], half_mode, 4);
2219 emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
2220 emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
2225 [(set (match_operand:V64 0 "memory_operand" "")
2226 (match_operand:V64 1 "const_zero_operand" ""))]
2230 && ! mem_min_alignment (operands[0], 8)))
2231 && offsettable_memref_p (operands[0])"
2232 [(clobber (const_int 0))]
2234 enum machine_mode half_mode;
2237 /* We can be expanded for DFmode or integral vector modes. */
2238 if (<V64:MODE>mode == DFmode)
2243 dest1 = adjust_address (operands[0], half_mode, 0);
2244 dest2 = adjust_address (operands[0], half_mode, 4);
2246 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2247 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2252 [(set (match_operand:V64 0 "register_operand" "")
2253 (match_operand:V64 1 "const_zero_operand" ""))]
2256 && ((GET_CODE (operands[0]) == REG
2257 && REGNO (operands[0]) < 32)
2258 || (GET_CODE (operands[0]) == SUBREG
2259 && GET_CODE (SUBREG_REG (operands[0])) == REG
2260 && REGNO (SUBREG_REG (operands[0])) < 32))"
2261 [(clobber (const_int 0))]
2263 enum machine_mode half_mode;
2264 rtx set_dest = operands[0];
2267 /* We can be expanded for DFmode or integral vector modes. */
2268 if (<V64:MODE>mode == DFmode)
2273 dest1 = gen_highpart (half_mode, set_dest);
2274 dest2 = gen_lowpart (half_mode, set_dest);
2275 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2276 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2280 (define_expand "movtf"
2281 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2282 (match_operand:TF 1 "general_operand" ""))]
2285 if (sparc_expand_move (TFmode, operands))
2289 (define_insn "*movtf_insn_sp32"
2290 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2291 (match_operand:TF 1 "input_operand" "G,oe,GeUr,o,roG"))]
2294 && (register_operand (operands[0], TFmode)
2295 || register_or_zero_operand (operands[1], TFmode))"
2297 [(set_attr "length" "4")])
2299 ;; Exactly the same as above, except that all `e' cases are deleted.
2300 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2303 (define_insn "*movtf_insn_sp32_no_fpu"
2304 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2305 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
2308 && (register_operand (operands[0], TFmode)
2309 || register_or_zero_operand (operands[1], TFmode))"
2311 [(set_attr "length" "4")])
2313 (define_insn "*movtf_insn_sp64"
2314 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2315 (match_operand:TF 1 "input_operand" "G,oe,Ger,roG"))]
2318 && ! TARGET_HARD_QUAD
2319 && (register_operand (operands[0], TFmode)
2320 || register_or_zero_operand (operands[1], TFmode))"
2322 [(set_attr "length" "2")])
2324 (define_insn "*movtf_insn_sp64_hq"
2325 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2326 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
2330 && (register_operand (operands[0], TFmode)
2331 || register_or_zero_operand (operands[1], TFmode))"
2339 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2340 (set_attr "length" "2,*,*,*,2,2")])
2342 (define_insn "*movtf_insn_sp64_no_fpu"
2343 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2344 (match_operand:TF 1 "input_operand" "orG,rG"))]
2347 && (register_operand (operands[0], TFmode)
2348 || register_or_zero_operand (operands[1], TFmode))"
2350 [(set_attr "length" "2")])
2352 ;; Now all the splits to handle multi-insn TF mode moves.
2354 [(set (match_operand:TF 0 "register_operand" "")
2355 (match_operand:TF 1 "register_operand" ""))]
2359 && ! TARGET_HARD_QUAD)
2360 || ! fp_register_operand (operands[0], TFmode))"
2361 [(clobber (const_int 0))]
2363 rtx set_dest = operands[0];
2364 rtx set_src = operands[1];
2368 dest1 = gen_df_reg (set_dest, 0);
2369 dest2 = gen_df_reg (set_dest, 1);
2370 src1 = gen_df_reg (set_src, 0);
2371 src2 = gen_df_reg (set_src, 1);
2373 /* Now emit using the real source and destination we found, swapping
2374 the order if we detect overlap. */
2375 if (reg_overlap_mentioned_p (dest1, src2))
2377 emit_insn (gen_movdf (dest2, src2));
2378 emit_insn (gen_movdf (dest1, src1));
2382 emit_insn (gen_movdf (dest1, src1));
2383 emit_insn (gen_movdf (dest2, src2));
2389 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2390 (match_operand:TF 1 "const_zero_operand" ""))]
2392 [(clobber (const_int 0))]
2394 rtx set_dest = operands[0];
2397 switch (GET_CODE (set_dest))
2400 dest1 = gen_df_reg (set_dest, 0);
2401 dest2 = gen_df_reg (set_dest, 1);
2404 dest1 = adjust_address (set_dest, DFmode, 0);
2405 dest2 = adjust_address (set_dest, DFmode, 8);
2411 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2412 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2417 [(set (match_operand:TF 0 "register_operand" "")
2418 (match_operand:TF 1 "memory_operand" ""))]
2420 && offsettable_memref_p (operands[1])
2422 || ! TARGET_HARD_QUAD
2423 || ! fp_register_operand (operands[0], TFmode)))"
2424 [(clobber (const_int 0))]
2426 rtx word0 = adjust_address (operands[1], DFmode, 0);
2427 rtx word1 = adjust_address (operands[1], DFmode, 8);
2428 rtx set_dest, dest1, dest2;
2430 set_dest = operands[0];
2432 dest1 = gen_df_reg (set_dest, 0);
2433 dest2 = gen_df_reg (set_dest, 1);
2435 /* Now output, ordering such that we don't clobber any registers
2436 mentioned in the address. */
2437 if (reg_overlap_mentioned_p (dest1, word1))
2440 emit_insn (gen_movdf (dest2, word1));
2441 emit_insn (gen_movdf (dest1, word0));
2445 emit_insn (gen_movdf (dest1, word0));
2446 emit_insn (gen_movdf (dest2, word1));
2452 [(set (match_operand:TF 0 "memory_operand" "")
2453 (match_operand:TF 1 "register_operand" ""))]
2455 && offsettable_memref_p (operands[0])
2457 || ! TARGET_HARD_QUAD
2458 || ! fp_register_operand (operands[1], TFmode)))"
2459 [(clobber (const_int 0))]
2461 rtx set_src = operands[1];
2463 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2464 gen_df_reg (set_src, 0)));
2465 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2466 gen_df_reg (set_src, 1)));
2471 ;; SPARC-V9 conditional move instructions
2473 ;; We can handle larger constants here for some flavors, but for now we keep
2474 ;; it simple and only allow those constants supported by all flavors.
2475 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2476 ;; 3 contains the constant if one is present, but we handle either for
2477 ;; generality (sparc.c puts a constant in operand 2).
2479 (define_expand "mov<I:mode>cc"
2480 [(set (match_operand:I 0 "register_operand" "")
2481 (if_then_else:I (match_operand 1 "comparison_operator" "")
2482 (match_operand:I 2 "arith10_operand" "")
2483 (match_operand:I 3 "arith10_operand" "")))]
2484 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2486 enum rtx_code code = GET_CODE (operands[1]);
2489 if (GET_MODE (XEXP (operands[1], 0)) == DImode
2493 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2495 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2496 GET_CODE (operands[1]));
2498 if (XEXP (operands[1], 1) == const0_rtx
2499 && GET_CODE (XEXP (operands[1], 0)) == REG
2500 && GET_MODE (XEXP (operands[1], 0)) == DImode
2501 && v9_regcmp_p (code))
2502 cc_reg = XEXP (operands[1], 0);
2504 cc_reg = gen_compare_reg (operands[1]);
2506 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2509 (define_expand "mov<F:mode>cc"
2510 [(set (match_operand:F 0 "register_operand" "")
2511 (if_then_else:F (match_operand 1 "comparison_operator" "")
2512 (match_operand:F 2 "register_operand" "")
2513 (match_operand:F 3 "register_operand" "")))]
2514 "TARGET_V9 && TARGET_FPU"
2516 enum rtx_code code = GET_CODE (operands[1]);
2519 if (GET_MODE (XEXP (operands[1], 0)) == DImode
2523 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2525 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2526 GET_CODE (operands[1]));
2528 if (XEXP (operands[1], 1) == const0_rtx
2529 && GET_CODE (XEXP (operands[1], 0)) == REG
2530 && GET_MODE (XEXP (operands[1], 0)) == DImode
2531 && v9_regcmp_p (code))
2532 cc_reg = XEXP (operands[1], 0);
2534 cc_reg = gen_compare_reg (operands[1]);
2536 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2539 ;; Conditional move define_insns
2541 (define_insn "*mov<I:mode>_cc_v9"
2542 [(set (match_operand:I 0 "register_operand" "=r,r")
2543 (if_then_else:I (match_operator 1 "comparison_operator"
2544 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2546 (match_operand:I 3 "arith11_operand" "rL,0")
2547 (match_operand:I 4 "arith11_operand" "0,rL")))]
2548 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2551 mov%c1\t%x2, %4, %0"
2552 [(set_attr "type" "cmove")])
2554 (define_insn "*mov<I:mode>_cc_reg_sp64"
2555 [(set (match_operand:I 0 "register_operand" "=r,r")
2556 (if_then_else:I (match_operator 1 "v9_register_compare_operator"
2557 [(match_operand:DI 2 "register_operand" "r,r")
2559 (match_operand:I 3 "arith10_operand" "rM,0")
2560 (match_operand:I 4 "arith10_operand" "0,rM")))]
2563 movr%D1\t%2, %r3, %0
2564 movr%d1\t%2, %r4, %0"
2565 [(set_attr "type" "cmove")])
2567 (define_insn "*movsf_cc_v9"
2568 [(set (match_operand:SF 0 "register_operand" "=f,f")
2569 (if_then_else:SF (match_operator 1 "comparison_operator"
2570 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2572 (match_operand:SF 3 "register_operand" "f,0")
2573 (match_operand:SF 4 "register_operand" "0,f")))]
2574 "TARGET_V9 && TARGET_FPU"
2576 fmovs%C1\t%x2, %3, %0
2577 fmovs%c1\t%x2, %4, %0"
2578 [(set_attr "type" "fpcmove")])
2580 (define_insn "*movsf_cc_reg_sp64"
2581 [(set (match_operand:SF 0 "register_operand" "=f,f")
2582 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
2583 [(match_operand:DI 2 "register_operand" "r,r")
2585 (match_operand:SF 3 "register_operand" "f,0")
2586 (match_operand:SF 4 "register_operand" "0,f")))]
2587 "TARGET_ARCH64 && TARGET_FPU"
2589 fmovrs%D1\t%2, %3, %0
2590 fmovrs%d1\t%2, %4, %0"
2591 [(set_attr "type" "fpcrmove")])
2593 ;; Named because invoked by movtf_cc_v9
2594 (define_insn "movdf_cc_v9"
2595 [(set (match_operand:DF 0 "register_operand" "=e,e")
2596 (if_then_else:DF (match_operator 1 "comparison_operator"
2597 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2599 (match_operand:DF 3 "register_operand" "e,0")
2600 (match_operand:DF 4 "register_operand" "0,e")))]
2601 "TARGET_V9 && TARGET_FPU"
2603 fmovd%C1\t%x2, %3, %0
2604 fmovd%c1\t%x2, %4, %0"
2605 [(set_attr "type" "fpcmove")
2606 (set_attr "fptype" "double")])
2608 ;; Named because invoked by movtf_cc_reg_sp64
2609 (define_insn "movdf_cc_reg_sp64"
2610 [(set (match_operand:DF 0 "register_operand" "=e,e")
2611 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
2612 [(match_operand:DI 2 "register_operand" "r,r")
2614 (match_operand:DF 3 "register_operand" "e,0")
2615 (match_operand:DF 4 "register_operand" "0,e")))]
2616 "TARGET_ARCH64 && TARGET_FPU"
2618 fmovrd%D1\t%2, %3, %0
2619 fmovrd%d1\t%2, %4, %0"
2620 [(set_attr "type" "fpcrmove")
2621 (set_attr "fptype" "double")])
2623 (define_insn "*movtf_cc_hq_v9"
2624 [(set (match_operand:TF 0 "register_operand" "=e,e")
2625 (if_then_else:TF (match_operator 1 "comparison_operator"
2626 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2628 (match_operand:TF 3 "register_operand" "e,0")
2629 (match_operand:TF 4 "register_operand" "0,e")))]
2630 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2632 fmovq%C1\t%x2, %3, %0
2633 fmovq%c1\t%x2, %4, %0"
2634 [(set_attr "type" "fpcmove")])
2636 (define_insn "*movtf_cc_reg_hq_sp64"
2637 [(set (match_operand:TF 0 "register_operand" "=e,e")
2638 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2639 [(match_operand:DI 2 "register_operand" "r,r")
2641 (match_operand:TF 3 "register_operand" "e,0")
2642 (match_operand:TF 4 "register_operand" "0,e")))]
2643 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
2645 fmovrq%D1\t%2, %3, %0
2646 fmovrq%d1\t%2, %4, %0"
2647 [(set_attr "type" "fpcrmove")])
2649 (define_insn_and_split "*movtf_cc_v9"
2650 [(set (match_operand:TF 0 "register_operand" "=e,e")
2651 (if_then_else:TF (match_operator 1 "comparison_operator"
2652 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2654 (match_operand:TF 3 "register_operand" "e,0")
2655 (match_operand:TF 4 "register_operand" "0,e")))]
2656 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
2658 "&& reload_completed"
2659 [(clobber (const_int 0))]
2661 rtx set_dest = operands[0];
2662 rtx set_srca = operands[3];
2663 rtx set_srcb = operands[4];
2664 int third = rtx_equal_p (set_dest, set_srca);
2666 rtx srca1, srca2, srcb1, srcb2;
2668 dest1 = gen_df_reg (set_dest, 0);
2669 dest2 = gen_df_reg (set_dest, 1);
2670 srca1 = gen_df_reg (set_srca, 0);
2671 srca2 = gen_df_reg (set_srca, 1);
2672 srcb1 = gen_df_reg (set_srcb, 0);
2673 srcb2 = gen_df_reg (set_srcb, 1);
2675 /* Now emit using the real source and destination we found, swapping
2676 the order if we detect overlap. */
2677 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2678 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2680 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2681 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2685 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2686 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2690 [(set_attr "length" "2")])
2692 (define_insn_and_split "*movtf_cc_reg_sp64"
2693 [(set (match_operand:TF 0 "register_operand" "=e,e")
2694 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2695 [(match_operand:DI 2 "register_operand" "r,r")
2697 (match_operand:TF 3 "register_operand" "e,0")
2698 (match_operand:TF 4 "register_operand" "0,e")))]
2699 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
2701 "&& reload_completed"
2702 [(clobber (const_int 0))]
2704 rtx set_dest = operands[0];
2705 rtx set_srca = operands[3];
2706 rtx set_srcb = operands[4];
2707 int third = rtx_equal_p (set_dest, set_srca);
2709 rtx srca1, srca2, srcb1, srcb2;
2711 dest1 = gen_df_reg (set_dest, 0);
2712 dest2 = gen_df_reg (set_dest, 1);
2713 srca1 = gen_df_reg (set_srca, 0);
2714 srca2 = gen_df_reg (set_srca, 1);
2715 srcb1 = gen_df_reg (set_srcb, 0);
2716 srcb2 = gen_df_reg (set_srcb, 1);
2718 /* Now emit using the real source and destination we found, swapping
2719 the order if we detect overlap. */
2720 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2721 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2723 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2724 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2728 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2729 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2733 [(set_attr "length" "2")])
2736 ;; Zero-extension instructions
2738 ;; These patterns originally accepted general_operands, however, slightly
2739 ;; better code is generated by only accepting register_operands, and then
2740 ;; letting combine generate the ldu[hb] insns.
2742 (define_expand "zero_extendhisi2"
2743 [(set (match_operand:SI 0 "register_operand" "")
2744 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2747 rtx temp = gen_reg_rtx (SImode);
2748 rtx shift_16 = GEN_INT (16);
2749 int op1_subbyte = 0;
2751 if (GET_CODE (operand1) == SUBREG)
2753 op1_subbyte = SUBREG_BYTE (operand1);
2754 op1_subbyte /= GET_MODE_SIZE (SImode);
2755 op1_subbyte *= GET_MODE_SIZE (SImode);
2756 operand1 = XEXP (operand1, 0);
2759 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2761 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2765 (define_insn "*zero_extendhisi2_insn"
2766 [(set (match_operand:SI 0 "register_operand" "=r")
2767 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2770 [(set_attr "type" "load")
2771 (set_attr "us3load_type" "3cycle")])
2773 (define_expand "zero_extendqihi2"
2774 [(set (match_operand:HI 0 "register_operand" "")
2775 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2779 (define_insn "*zero_extendqihi2_insn"
2780 [(set (match_operand:HI 0 "register_operand" "=r,r")
2781 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
2782 "GET_CODE (operands[1]) != CONST_INT"
2786 [(set_attr "type" "*,load")
2787 (set_attr "us3load_type" "*,3cycle")])
2789 (define_expand "zero_extendqisi2"
2790 [(set (match_operand:SI 0 "register_operand" "")
2791 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2795 (define_insn "*zero_extendqisi2_insn"
2796 [(set (match_operand:SI 0 "register_operand" "=r,r")
2797 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
2798 "GET_CODE (operands[1]) != CONST_INT"
2802 [(set_attr "type" "*,load")
2803 (set_attr "us3load_type" "*,3cycle")])
2805 (define_expand "zero_extendqidi2"
2806 [(set (match_operand:DI 0 "register_operand" "")
2807 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2811 (define_insn "*zero_extendqidi2_insn"
2812 [(set (match_operand:DI 0 "register_operand" "=r,r")
2813 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
2814 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2818 [(set_attr "type" "*,load")
2819 (set_attr "us3load_type" "*,3cycle")])
2821 (define_expand "zero_extendhidi2"
2822 [(set (match_operand:DI 0 "register_operand" "")
2823 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2826 rtx temp = gen_reg_rtx (DImode);
2827 rtx shift_48 = GEN_INT (48);
2828 int op1_subbyte = 0;
2830 if (GET_CODE (operand1) == SUBREG)
2832 op1_subbyte = SUBREG_BYTE (operand1);
2833 op1_subbyte /= GET_MODE_SIZE (DImode);
2834 op1_subbyte *= GET_MODE_SIZE (DImode);
2835 operand1 = XEXP (operand1, 0);
2838 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
2840 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
2844 (define_insn "*zero_extendhidi2_insn"
2845 [(set (match_operand:DI 0 "register_operand" "=r")
2846 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2849 [(set_attr "type" "load")
2850 (set_attr "us3load_type" "3cycle")])
2852 ;; ??? Write truncdisi pattern using sra?
2854 (define_expand "zero_extendsidi2"
2855 [(set (match_operand:DI 0 "register_operand" "")
2856 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
2860 (define_insn "*zero_extendsidi2_insn_sp64"
2861 [(set (match_operand:DI 0 "register_operand" "=r,r")
2862 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
2863 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2867 [(set_attr "type" "shift,load")])
2869 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
2870 [(set (match_operand:DI 0 "register_operand" "=r")
2871 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
2874 "&& reload_completed"
2875 [(set (match_dup 2) (match_dup 3))
2876 (set (match_dup 4) (match_dup 5))]
2880 dest1 = gen_highpart (SImode, operands[0]);
2881 dest2 = gen_lowpart (SImode, operands[0]);
2883 /* Swap the order in case of overlap. */
2884 if (REGNO (dest1) == REGNO (operands[1]))
2886 operands[2] = dest2;
2887 operands[3] = operands[1];
2888 operands[4] = dest1;
2889 operands[5] = const0_rtx;
2893 operands[2] = dest1;
2894 operands[3] = const0_rtx;
2895 operands[4] = dest2;
2896 operands[5] = operands[1];
2899 [(set_attr "length" "2")])
2901 ;; Simplify comparisons of extended values.
2903 (define_insn "*cmp_zero_extendqisi2"
2905 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
2908 "andcc\t%0, 0xff, %%g0"
2909 [(set_attr "type" "compare")])
2911 (define_insn "*cmp_zero_qi"
2913 (compare:CC (match_operand:QI 0 "register_operand" "r")
2916 "andcc\t%0, 0xff, %%g0"
2917 [(set_attr "type" "compare")])
2919 (define_insn "*cmp_zero_extendqisi2_set"
2921 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
2923 (set (match_operand:SI 0 "register_operand" "=r")
2924 (zero_extend:SI (match_dup 1)))]
2926 "andcc\t%1, 0xff, %0"
2927 [(set_attr "type" "compare")])
2929 (define_insn "*cmp_zero_extendqisi2_andcc_set"
2931 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
2934 (set (match_operand:SI 0 "register_operand" "=r")
2935 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
2937 "andcc\t%1, 0xff, %0"
2938 [(set_attr "type" "compare")])
2940 (define_insn "*cmp_zero_extendqidi2"
2942 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
2945 "andcc\t%0, 0xff, %%g0"
2946 [(set_attr "type" "compare")])
2948 (define_insn "*cmp_zero_qi_sp64"
2950 (compare:CCX (match_operand:QI 0 "register_operand" "r")
2953 "andcc\t%0, 0xff, %%g0"
2954 [(set_attr "type" "compare")])
2956 (define_insn "*cmp_zero_extendqidi2_set"
2958 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
2960 (set (match_operand:DI 0 "register_operand" "=r")
2961 (zero_extend:DI (match_dup 1)))]
2963 "andcc\t%1, 0xff, %0"
2964 [(set_attr "type" "compare")])
2966 (define_insn "*cmp_zero_extendqidi2_andcc_set"
2968 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
2971 (set (match_operand:DI 0 "register_operand" "=r")
2972 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
2974 "andcc\t%1, 0xff, %0"
2975 [(set_attr "type" "compare")])
2977 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
2979 (define_insn "*cmp_siqi_trunc"
2981 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
2984 "andcc\t%0, 0xff, %%g0"
2985 [(set_attr "type" "compare")])
2987 (define_insn "*cmp_siqi_trunc_set"
2989 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
2991 (set (match_operand:QI 0 "register_operand" "=r")
2992 (subreg:QI (match_dup 1) 3))]
2994 "andcc\t%1, 0xff, %0"
2995 [(set_attr "type" "compare")])
2997 (define_insn "*cmp_diqi_trunc"
2999 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3002 "andcc\t%0, 0xff, %%g0"
3003 [(set_attr "type" "compare")])
3005 (define_insn "*cmp_diqi_trunc_set"
3007 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3009 (set (match_operand:QI 0 "register_operand" "=r")
3010 (subreg:QI (match_dup 1) 7))]
3012 "andcc\t%1, 0xff, %0"
3013 [(set_attr "type" "compare")])
3016 ;; Sign-extension instructions
3018 ;; These patterns originally accepted general_operands, however, slightly
3019 ;; better code is generated by only accepting register_operands, and then
3020 ;; letting combine generate the lds[hb] insns.
3022 (define_expand "extendhisi2"
3023 [(set (match_operand:SI 0 "register_operand" "")
3024 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3027 rtx temp = gen_reg_rtx (SImode);
3028 rtx shift_16 = GEN_INT (16);
3029 int op1_subbyte = 0;
3031 if (GET_CODE (operand1) == SUBREG)
3033 op1_subbyte = SUBREG_BYTE (operand1);
3034 op1_subbyte /= GET_MODE_SIZE (SImode);
3035 op1_subbyte *= GET_MODE_SIZE (SImode);
3036 operand1 = XEXP (operand1, 0);
3039 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3041 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3045 (define_insn "*sign_extendhisi2_insn"
3046 [(set (match_operand:SI 0 "register_operand" "=r")
3047 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3050 [(set_attr "type" "sload")
3051 (set_attr "us3load_type" "3cycle")])
3053 (define_expand "extendqihi2"
3054 [(set (match_operand:HI 0 "register_operand" "")
3055 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3058 rtx temp = gen_reg_rtx (SImode);
3059 rtx shift_24 = GEN_INT (24);
3060 int op1_subbyte = 0;
3061 int op0_subbyte = 0;
3063 if (GET_CODE (operand1) == SUBREG)
3065 op1_subbyte = SUBREG_BYTE (operand1);
3066 op1_subbyte /= GET_MODE_SIZE (SImode);
3067 op1_subbyte *= GET_MODE_SIZE (SImode);
3068 operand1 = XEXP (operand1, 0);
3070 if (GET_CODE (operand0) == SUBREG)
3072 op0_subbyte = SUBREG_BYTE (operand0);
3073 op0_subbyte /= GET_MODE_SIZE (SImode);
3074 op0_subbyte *= GET_MODE_SIZE (SImode);
3075 operand0 = XEXP (operand0, 0);
3077 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3079 if (GET_MODE (operand0) != SImode)
3080 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3081 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3085 (define_insn "*sign_extendqihi2_insn"
3086 [(set (match_operand:HI 0 "register_operand" "=r")
3087 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3090 [(set_attr "type" "sload")
3091 (set_attr "us3load_type" "3cycle")])
3093 (define_expand "extendqisi2"
3094 [(set (match_operand:SI 0 "register_operand" "")
3095 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3098 rtx temp = gen_reg_rtx (SImode);
3099 rtx shift_24 = GEN_INT (24);
3100 int op1_subbyte = 0;
3102 if (GET_CODE (operand1) == SUBREG)
3104 op1_subbyte = SUBREG_BYTE (operand1);
3105 op1_subbyte /= GET_MODE_SIZE (SImode);
3106 op1_subbyte *= GET_MODE_SIZE (SImode);
3107 operand1 = XEXP (operand1, 0);
3110 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3112 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3116 (define_insn "*sign_extendqisi2_insn"
3117 [(set (match_operand:SI 0 "register_operand" "=r")
3118 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3121 [(set_attr "type" "sload")
3122 (set_attr "us3load_type" "3cycle")])
3124 (define_expand "extendqidi2"
3125 [(set (match_operand:DI 0 "register_operand" "")
3126 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3129 rtx temp = gen_reg_rtx (DImode);
3130 rtx shift_56 = GEN_INT (56);
3131 int op1_subbyte = 0;
3133 if (GET_CODE (operand1) == SUBREG)
3135 op1_subbyte = SUBREG_BYTE (operand1);
3136 op1_subbyte /= GET_MODE_SIZE (DImode);
3137 op1_subbyte *= GET_MODE_SIZE (DImode);
3138 operand1 = XEXP (operand1, 0);
3141 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3143 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3147 (define_insn "*sign_extendqidi2_insn"
3148 [(set (match_operand:DI 0 "register_operand" "=r")
3149 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3152 [(set_attr "type" "sload")
3153 (set_attr "us3load_type" "3cycle")])
3155 (define_expand "extendhidi2"
3156 [(set (match_operand:DI 0 "register_operand" "")
3157 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3160 rtx temp = gen_reg_rtx (DImode);
3161 rtx shift_48 = GEN_INT (48);
3162 int op1_subbyte = 0;
3164 if (GET_CODE (operand1) == SUBREG)
3166 op1_subbyte = SUBREG_BYTE (operand1);
3167 op1_subbyte /= GET_MODE_SIZE (DImode);
3168 op1_subbyte *= GET_MODE_SIZE (DImode);
3169 operand1 = XEXP (operand1, 0);
3172 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3174 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3178 (define_insn "*sign_extendhidi2_insn"
3179 [(set (match_operand:DI 0 "register_operand" "=r")
3180 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3183 [(set_attr "type" "sload")
3184 (set_attr "us3load_type" "3cycle")])
3186 (define_expand "extendsidi2"
3187 [(set (match_operand:DI 0 "register_operand" "")
3188 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3192 (define_insn "*sign_extendsidi2_insn"
3193 [(set (match_operand:DI 0 "register_operand" "=r,r")
3194 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3199 [(set_attr "type" "shift,sload")
3200 (set_attr "us3load_type" "*,3cycle")])
3203 ;; Special pattern for optimizing bit-field compares. This is needed
3204 ;; because combine uses this as a canonical form.
3206 (define_insn "*cmp_zero_extract"
3209 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3210 (match_operand:SI 1 "small_int_operand" "I")
3211 (match_operand:SI 2 "small_int_operand" "I"))
3213 "INTVAL (operands[2]) > 19"
3215 int len = INTVAL (operands[1]);
3216 int pos = 32 - INTVAL (operands[2]) - len;
3217 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3218 operands[1] = GEN_INT (mask);
3219 return "andcc\t%0, %1, %%g0";
3221 [(set_attr "type" "compare")])
3223 (define_insn "*cmp_zero_extract_sp64"
3226 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3227 (match_operand:SI 1 "small_int_operand" "I")
3228 (match_operand:SI 2 "small_int_operand" "I"))
3230 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3232 int len = INTVAL (operands[1]);
3233 int pos = 64 - INTVAL (operands[2]) - len;
3234 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3235 operands[1] = GEN_INT (mask);
3236 return "andcc\t%0, %1, %%g0";
3238 [(set_attr "type" "compare")])
3241 ;; Conversions between float, double and long double.
3243 (define_insn "extendsfdf2"
3244 [(set (match_operand:DF 0 "register_operand" "=e")
3246 (match_operand:SF 1 "register_operand" "f")))]
3249 [(set_attr "type" "fp")
3250 (set_attr "fptype" "double")])
3252 (define_expand "extendsftf2"
3253 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3255 (match_operand:SF 1 "register_operand" "")))]
3256 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3257 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3259 (define_insn "*extendsftf2_hq"
3260 [(set (match_operand:TF 0 "register_operand" "=e")
3262 (match_operand:SF 1 "register_operand" "f")))]
3263 "TARGET_FPU && TARGET_HARD_QUAD"
3265 [(set_attr "type" "fp")])
3267 (define_expand "extenddftf2"
3268 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3270 (match_operand:DF 1 "register_operand" "")))]
3271 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3272 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3274 (define_insn "*extenddftf2_hq"
3275 [(set (match_operand:TF 0 "register_operand" "=e")
3277 (match_operand:DF 1 "register_operand" "e")))]
3278 "TARGET_FPU && TARGET_HARD_QUAD"
3280 [(set_attr "type" "fp")])
3282 (define_insn "truncdfsf2"
3283 [(set (match_operand:SF 0 "register_operand" "=f")
3285 (match_operand:DF 1 "register_operand" "e")))]
3288 [(set_attr "type" "fp")
3289 (set_attr "fptype" "double")])
3291 (define_expand "trunctfsf2"
3292 [(set (match_operand:SF 0 "register_operand" "")
3294 (match_operand:TF 1 "general_operand" "")))]
3295 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3296 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3298 (define_insn "*trunctfsf2_hq"
3299 [(set (match_operand:SF 0 "register_operand" "=f")
3301 (match_operand:TF 1 "register_operand" "e")))]
3302 "TARGET_FPU && TARGET_HARD_QUAD"
3304 [(set_attr "type" "fp")])
3306 (define_expand "trunctfdf2"
3307 [(set (match_operand:DF 0 "register_operand" "")
3309 (match_operand:TF 1 "general_operand" "")))]
3310 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3311 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3313 (define_insn "*trunctfdf2_hq"
3314 [(set (match_operand:DF 0 "register_operand" "=e")
3316 (match_operand:TF 1 "register_operand" "e")))]
3317 "TARGET_FPU && TARGET_HARD_QUAD"
3319 [(set_attr "type" "fp")])
3322 ;; Conversion between fixed point and floating point.
3324 (define_insn "floatsisf2"
3325 [(set (match_operand:SF 0 "register_operand" "=f")
3326 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3329 [(set_attr "type" "fp")
3330 (set_attr "fptype" "double")])
3332 (define_insn "floatsidf2"
3333 [(set (match_operand:DF 0 "register_operand" "=e")
3334 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3337 [(set_attr "type" "fp")
3338 (set_attr "fptype" "double")])
3340 (define_expand "floatsitf2"
3341 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3342 (float:TF (match_operand:SI 1 "register_operand" "")))]
3343 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3344 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3346 (define_insn "*floatsitf2_hq"
3347 [(set (match_operand:TF 0 "register_operand" "=e")
3348 (float:TF (match_operand:SI 1 "register_operand" "f")))]
3349 "TARGET_FPU && TARGET_HARD_QUAD"
3351 [(set_attr "type" "fp")])
3353 (define_expand "floatunssitf2"
3354 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3355 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3356 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3357 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3359 ;; Now the same for 64 bit sources.
3361 (define_insn "floatdisf2"
3362 [(set (match_operand:SF 0 "register_operand" "=f")
3363 (float:SF (match_operand:DI 1 "register_operand" "e")))]
3364 "TARGET_V9 && TARGET_FPU"
3366 [(set_attr "type" "fp")
3367 (set_attr "fptype" "double")])
3369 (define_expand "floatunsdisf2"
3370 [(use (match_operand:SF 0 "register_operand" ""))
3371 (use (match_operand:DI 1 "general_operand" ""))]
3372 "TARGET_ARCH64 && TARGET_FPU"
3373 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3375 (define_insn "floatdidf2"
3376 [(set (match_operand:DF 0 "register_operand" "=e")
3377 (float:DF (match_operand:DI 1 "register_operand" "e")))]
3378 "TARGET_V9 && TARGET_FPU"
3380 [(set_attr "type" "fp")
3381 (set_attr "fptype" "double")])
3383 (define_expand "floatunsdidf2"
3384 [(use (match_operand:DF 0 "register_operand" ""))
3385 (use (match_operand:DI 1 "general_operand" ""))]
3386 "TARGET_ARCH64 && TARGET_FPU"
3387 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3389 (define_expand "floatditf2"
3390 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3391 (float:TF (match_operand:DI 1 "register_operand" "")))]
3392 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3393 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3395 (define_insn "*floatditf2_hq"
3396 [(set (match_operand:TF 0 "register_operand" "=e")
3397 (float:TF (match_operand:DI 1 "register_operand" "e")))]
3398 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3400 [(set_attr "type" "fp")])
3402 (define_expand "floatunsditf2"
3403 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3404 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3405 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3406 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3408 ;; Convert a float to an actual integer.
3409 ;; Truncation is performed as part of the conversion.
3411 (define_insn "fix_truncsfsi2"
3412 [(set (match_operand:SI 0 "register_operand" "=f")
3413 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3416 [(set_attr "type" "fp")
3417 (set_attr "fptype" "double")])
3419 (define_insn "fix_truncdfsi2"
3420 [(set (match_operand:SI 0 "register_operand" "=f")
3421 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3424 [(set_attr "type" "fp")
3425 (set_attr "fptype" "double")])
3427 (define_expand "fix_trunctfsi2"
3428 [(set (match_operand:SI 0 "register_operand" "")
3429 (fix:SI (match_operand:TF 1 "general_operand" "")))]
3430 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3431 "emit_tfmode_cvt (FIX, operands); DONE;")
3433 (define_insn "*fix_trunctfsi2_hq"
3434 [(set (match_operand:SI 0 "register_operand" "=f")
3435 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
3436 "TARGET_FPU && TARGET_HARD_QUAD"
3438 [(set_attr "type" "fp")])
3440 (define_expand "fixuns_trunctfsi2"
3441 [(set (match_operand:SI 0 "register_operand" "")
3442 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
3443 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3444 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3446 ;; Now the same, for V9 targets
3448 (define_insn "fix_truncsfdi2"
3449 [(set (match_operand:DI 0 "register_operand" "=e")
3450 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3451 "TARGET_V9 && TARGET_FPU"
3453 [(set_attr "type" "fp")
3454 (set_attr "fptype" "double")])
3456 (define_expand "fixuns_truncsfdi2"
3457 [(use (match_operand:DI 0 "register_operand" ""))
3458 (use (match_operand:SF 1 "general_operand" ""))]
3459 "TARGET_ARCH64 && TARGET_FPU"
3460 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
3462 (define_insn "fix_truncdfdi2"
3463 [(set (match_operand:DI 0 "register_operand" "=e")
3464 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3465 "TARGET_V9 && TARGET_FPU"
3467 [(set_attr "type" "fp")
3468 (set_attr "fptype" "double")])
3470 (define_expand "fixuns_truncdfdi2"
3471 [(use (match_operand:DI 0 "register_operand" ""))
3472 (use (match_operand:DF 1 "general_operand" ""))]
3473 "TARGET_ARCH64 && TARGET_FPU"
3474 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
3476 (define_expand "fix_trunctfdi2"
3477 [(set (match_operand:DI 0 "register_operand" "")
3478 (fix:DI (match_operand:TF 1 "general_operand" "")))]
3479 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3480 "emit_tfmode_cvt (FIX, operands); DONE;")
3482 (define_insn "*fix_trunctfdi2_hq"
3483 [(set (match_operand:DI 0 "register_operand" "=e")
3484 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
3485 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3487 [(set_attr "type" "fp")])
3489 (define_expand "fixuns_trunctfdi2"
3490 [(set (match_operand:DI 0 "register_operand" "")
3491 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
3492 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3493 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3496 ;; Integer addition/subtraction instructions.
3498 (define_expand "adddi3"
3499 [(set (match_operand:DI 0 "register_operand" "")
3500 (plus:DI (match_operand:DI 1 "register_operand" "")
3501 (match_operand:DI 2 "arith_double_add_operand" "")))]
3504 if (! TARGET_ARCH64)
3506 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3507 gen_rtx_SET (VOIDmode, operands[0],
3508 gen_rtx_PLUS (DImode, operands[1],
3510 gen_rtx_CLOBBER (VOIDmode,
3511 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3516 (define_insn_and_split "*adddi3_insn_sp32"
3517 [(set (match_operand:DI 0 "register_operand" "=r")
3518 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3519 (match_operand:DI 2 "arith_double_operand" "rHI")))
3520 (clobber (reg:CC 100))]
3523 "&& reload_completed"
3524 [(parallel [(set (reg:CC_NOOV 100)
3525 (compare:CC_NOOV (plus:SI (match_dup 4)
3529 (plus:SI (match_dup 4) (match_dup 5)))])
3531 (plus:SI (plus:SI (match_dup 7)
3533 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3535 operands[3] = gen_lowpart (SImode, operands[0]);
3536 operands[4] = gen_lowpart (SImode, operands[1]);
3537 operands[5] = gen_lowpart (SImode, operands[2]);
3538 operands[6] = gen_highpart (SImode, operands[0]);
3539 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3540 #if HOST_BITS_PER_WIDE_INT == 32
3541 if (GET_CODE (operands[2]) == CONST_INT)
3543 if (INTVAL (operands[2]) < 0)
3544 operands[8] = constm1_rtx;
3546 operands[8] = const0_rtx;
3550 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3552 [(set_attr "length" "2")])
3554 ;; LTU here means "carry set"
3556 [(set (match_operand:SI 0 "register_operand" "=r")
3557 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3558 (match_operand:SI 2 "arith_operand" "rI"))
3559 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3562 [(set_attr "type" "ialuX")])
3564 (define_insn_and_split "*addx_extend_sp32"
3565 [(set (match_operand:DI 0 "register_operand" "=r")
3566 (zero_extend:DI (plus:SI (plus:SI
3567 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3568 (match_operand:SI 2 "arith_operand" "rI"))
3569 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3572 "&& reload_completed"
3573 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
3574 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
3575 (set (match_dup 4) (const_int 0))]
3576 "operands[3] = gen_lowpart (SImode, operands[0]);
3577 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
3578 [(set_attr "length" "2")])
3580 (define_insn "*addx_extend_sp64"
3581 [(set (match_operand:DI 0 "register_operand" "=r")
3582 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3583 (match_operand:SI 2 "arith_operand" "rI"))
3584 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3587 [(set_attr "type" "ialuX")])
3589 (define_insn_and_split "*adddi3_extend_sp32"
3590 [(set (match_operand:DI 0 "register_operand" "=r")
3591 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3592 (match_operand:DI 2 "register_operand" "r")))
3593 (clobber (reg:CC 100))]
3596 "&& reload_completed"
3597 [(parallel [(set (reg:CC_NOOV 100)
3598 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
3600 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
3602 (plus:SI (plus:SI (match_dup 4) (const_int 0))
3603 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3604 "operands[3] = gen_lowpart (SImode, operands[2]);
3605 operands[4] = gen_highpart (SImode, operands[2]);
3606 operands[5] = gen_lowpart (SImode, operands[0]);
3607 operands[6] = gen_highpart (SImode, operands[0]);"
3608 [(set_attr "length" "2")])
3610 (define_insn "*adddi3_sp64"
3611 [(set (match_operand:DI 0 "register_operand" "=r,r")
3612 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3613 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3619 (define_insn "addsi3"
3620 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3621 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
3622 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3627 fpadd32s\t%1, %2, %0"
3628 [(set_attr "type" "*,*,fga")
3629 (set_attr "fptype" "*,*,single")])
3631 (define_insn "*cmp_cc_plus"
3632 [(set (reg:CC_NOOV 100)
3633 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3634 (match_operand:SI 1 "arith_operand" "rI"))
3637 "addcc\t%0, %1, %%g0"
3638 [(set_attr "type" "compare")])
3640 (define_insn "*cmp_ccx_plus"
3641 [(set (reg:CCX_NOOV 100)
3642 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
3643 (match_operand:DI 1 "arith_operand" "rI"))
3646 "addcc\t%0, %1, %%g0"
3647 [(set_attr "type" "compare")])
3649 (define_insn "*cmp_cc_plus_set"
3650 [(set (reg:CC_NOOV 100)
3651 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3652 (match_operand:SI 2 "arith_operand" "rI"))
3654 (set (match_operand:SI 0 "register_operand" "=r")
3655 (plus:SI (match_dup 1) (match_dup 2)))]
3658 [(set_attr "type" "compare")])
3660 (define_insn "*cmp_ccx_plus_set"
3661 [(set (reg:CCX_NOOV 100)
3662 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
3663 (match_operand:DI 2 "arith_operand" "rI"))
3665 (set (match_operand:DI 0 "register_operand" "=r")
3666 (plus:DI (match_dup 1) (match_dup 2)))]
3669 [(set_attr "type" "compare")])
3671 (define_expand "subdi3"
3672 [(set (match_operand:DI 0 "register_operand" "")
3673 (minus:DI (match_operand:DI 1 "register_operand" "")
3674 (match_operand:DI 2 "arith_double_add_operand" "")))]
3677 if (! TARGET_ARCH64)
3679 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3680 gen_rtx_SET (VOIDmode, operands[0],
3681 gen_rtx_MINUS (DImode, operands[1],
3683 gen_rtx_CLOBBER (VOIDmode,
3684 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3689 (define_insn_and_split "*subdi3_insn_sp32"
3690 [(set (match_operand:DI 0 "register_operand" "=r")
3691 (minus:DI (match_operand:DI 1 "register_operand" "r")
3692 (match_operand:DI 2 "arith_double_operand" "rHI")))
3693 (clobber (reg:CC 100))]
3696 "&& reload_completed"
3697 [(parallel [(set (reg:CC_NOOV 100)
3698 (compare:CC_NOOV (minus:SI (match_dup 4)
3702 (minus:SI (match_dup 4) (match_dup 5)))])
3704 (minus:SI (minus:SI (match_dup 7)
3706 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3708 operands[3] = gen_lowpart (SImode, operands[0]);
3709 operands[4] = gen_lowpart (SImode, operands[1]);
3710 operands[5] = gen_lowpart (SImode, operands[2]);
3711 operands[6] = gen_highpart (SImode, operands[0]);
3712 operands[7] = gen_highpart (SImode, operands[1]);
3713 #if HOST_BITS_PER_WIDE_INT == 32
3714 if (GET_CODE (operands[2]) == CONST_INT)
3716 if (INTVAL (operands[2]) < 0)
3717 operands[8] = constm1_rtx;
3719 operands[8] = const0_rtx;
3723 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3725 [(set_attr "length" "2")])
3727 ;; LTU here means "carry set"
3729 [(set (match_operand:SI 0 "register_operand" "=r")
3730 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3731 (match_operand:SI 2 "arith_operand" "rI"))
3732 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3735 [(set_attr "type" "ialuX")])
3737 (define_insn "*subx_extend_sp64"
3738 [(set (match_operand:DI 0 "register_operand" "=r")
3739 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3740 (match_operand:SI 2 "arith_operand" "rI"))
3741 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3744 [(set_attr "type" "ialuX")])
3746 (define_insn_and_split "*subx_extend"
3747 [(set (match_operand:DI 0 "register_operand" "=r")
3748 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3749 (match_operand:SI 2 "arith_operand" "rI"))
3750 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3753 "&& reload_completed"
3754 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
3755 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
3756 (set (match_dup 4) (const_int 0))]
3757 "operands[3] = gen_lowpart (SImode, operands[0]);
3758 operands[4] = gen_highpart (SImode, operands[0]);"
3759 [(set_attr "length" "2")])
3761 (define_insn_and_split "*subdi3_extend_sp32"
3762 [(set (match_operand:DI 0 "register_operand" "=r")
3763 (minus:DI (match_operand:DI 1 "register_operand" "r")
3764 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
3765 (clobber (reg:CC 100))]
3768 "&& reload_completed"
3769 [(parallel [(set (reg:CC_NOOV 100)
3770 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
3772 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
3774 (minus:SI (minus:SI (match_dup 4) (const_int 0))
3775 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3776 "operands[3] = gen_lowpart (SImode, operands[1]);
3777 operands[4] = gen_highpart (SImode, operands[1]);
3778 operands[5] = gen_lowpart (SImode, operands[0]);
3779 operands[6] = gen_highpart (SImode, operands[0]);"
3780 [(set_attr "length" "2")])
3782 (define_insn "*subdi3_sp64"
3783 [(set (match_operand:DI 0 "register_operand" "=r,r")
3784 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
3785 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3791 (define_insn "subsi3"
3792 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3793 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
3794 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3799 fpsub32s\t%1, %2, %0"
3800 [(set_attr "type" "*,*,fga")
3801 (set_attr "fptype" "*,*,single")])
3803 (define_insn "*cmp_minus_cc"
3804 [(set (reg:CC_NOOV 100)
3805 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
3806 (match_operand:SI 1 "arith_operand" "rI"))
3809 "subcc\t%r0, %1, %%g0"
3810 [(set_attr "type" "compare")])
3812 (define_insn "*cmp_minus_ccx"
3813 [(set (reg:CCX_NOOV 100)
3814 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
3815 (match_operand:DI 1 "arith_operand" "rI"))
3818 "subcc\t%0, %1, %%g0"
3819 [(set_attr "type" "compare")])
3821 (define_insn "cmp_minus_cc_set"
3822 [(set (reg:CC_NOOV 100)
3823 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3824 (match_operand:SI 2 "arith_operand" "rI"))
3826 (set (match_operand:SI 0 "register_operand" "=r")
3827 (minus:SI (match_dup 1) (match_dup 2)))]
3829 "subcc\t%r1, %2, %0"
3830 [(set_attr "type" "compare")])
3832 (define_insn "*cmp_minus_ccx_set"
3833 [(set (reg:CCX_NOOV 100)
3834 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
3835 (match_operand:DI 2 "arith_operand" "rI"))
3837 (set (match_operand:DI 0 "register_operand" "=r")
3838 (minus:DI (match_dup 1) (match_dup 2)))]
3841 [(set_attr "type" "compare")])
3844 ;; Integer multiply/divide instructions.
3846 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
3847 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
3849 (define_insn "mulsi3"
3850 [(set (match_operand:SI 0 "register_operand" "=r")
3851 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3852 (match_operand:SI 2 "arith_operand" "rI")))]
3855 [(set_attr "type" "imul")])
3857 (define_expand "muldi3"
3858 [(set (match_operand:DI 0 "register_operand" "")
3859 (mult:DI (match_operand:DI 1 "arith_operand" "")
3860 (match_operand:DI 2 "arith_operand" "")))]
3861 "TARGET_ARCH64 || TARGET_V8PLUS"
3865 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
3870 (define_insn "*muldi3_sp64"
3871 [(set (match_operand:DI 0 "register_operand" "=r")
3872 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
3873 (match_operand:DI 2 "arith_operand" "rI")))]
3876 [(set_attr "type" "imul")])
3878 ;; V8plus wide multiply.
3880 (define_insn "muldi3_v8plus"
3881 [(set (match_operand:DI 0 "register_operand" "=r,h")
3882 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
3883 (match_operand:DI 2 "arith_operand" "rI,rI")))
3884 (clobber (match_scratch:SI 3 "=&h,X"))
3885 (clobber (match_scratch:SI 4 "=&h,X"))]
3888 if (sparc_check_64 (operands[1], insn) <= 0)
3889 output_asm_insn ("srl\t%L1, 0, %L1", operands);
3890 if (which_alternative == 1)
3891 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
3892 if (GET_CODE (operands[2]) == CONST_INT)
3894 if (which_alternative == 1)
3895 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
3897 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";
3899 else if (rtx_equal_p (operands[1], operands[2]))
3901 if (which_alternative == 1)
3902 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
3904 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";
3906 if (sparc_check_64 (operands[2], insn) <= 0)
3907 output_asm_insn ("srl\t%L2, 0, %L2", operands);
3908 if (which_alternative == 1)
3909 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";
3911 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";
3913 [(set_attr "type" "multi")
3914 (set_attr "length" "9,8")])
3916 (define_insn "*cmp_mul_set"
3918 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3919 (match_operand:SI 2 "arith_operand" "rI"))
3921 (set (match_operand:SI 0 "register_operand" "=r")
3922 (mult:SI (match_dup 1) (match_dup 2)))]
3923 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
3924 "smulcc\t%1, %2, %0"
3925 [(set_attr "type" "imul")])
3927 (define_expand "mulsidi3"
3928 [(set (match_operand:DI 0 "register_operand" "")
3929 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
3930 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
3933 if (CONSTANT_P (operands[2]))
3936 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
3938 else if (TARGET_ARCH32)
3939 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
3942 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
3948 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
3953 ;; V9 puts the 64-bit product in a 64-bit register. Only out or global
3954 ;; registers can hold 64-bit values in the V8plus environment.
3956 (define_insn "mulsidi3_v8plus"
3957 [(set (match_operand:DI 0 "register_operand" "=h,r")
3958 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
3959 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
3960 (clobber (match_scratch:SI 3 "=X,&h"))]
3963 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
3964 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
3965 [(set_attr "type" "multi")
3966 (set_attr "length" "2,3")])
3969 (define_insn "const_mulsidi3_v8plus"
3970 [(set (match_operand:DI 0 "register_operand" "=h,r")
3971 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
3972 (match_operand:DI 2 "small_int_operand" "I,I")))
3973 (clobber (match_scratch:SI 3 "=X,&h"))]
3976 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
3977 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
3978 [(set_attr "type" "multi")
3979 (set_attr "length" "2,3")])
3982 (define_insn "*mulsidi3_sp32"
3983 [(set (match_operand:DI 0 "register_operand" "=r")
3984 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3985 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
3988 return TARGET_SPARCLET
3989 ? "smuld\t%1, %2, %L0"
3990 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
3993 (if_then_else (eq_attr "isa" "sparclet")
3994 (const_string "imul") (const_string "multi")))
3995 (set (attr "length")
3996 (if_then_else (eq_attr "isa" "sparclet")
3997 (const_int 1) (const_int 2)))])
3999 (define_insn "*mulsidi3_sp64"
4000 [(set (match_operand:DI 0 "register_operand" "=r")
4001 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4002 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4003 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4005 [(set_attr "type" "imul")])
4007 ;; Extra pattern, because sign_extend of a constant isn't valid.
4010 (define_insn "const_mulsidi3_sp32"
4011 [(set (match_operand:DI 0 "register_operand" "=r")
4012 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4013 (match_operand:DI 2 "small_int_operand" "I")))]
4016 return TARGET_SPARCLET
4017 ? "smuld\t%1, %2, %L0"
4018 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4021 (if_then_else (eq_attr "isa" "sparclet")
4022 (const_string "imul") (const_string "multi")))
4023 (set (attr "length")
4024 (if_then_else (eq_attr "isa" "sparclet")
4025 (const_int 1) (const_int 2)))])
4027 (define_insn "const_mulsidi3_sp64"
4028 [(set (match_operand:DI 0 "register_operand" "=r")
4029 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4030 (match_operand:DI 2 "small_int_operand" "I")))]
4031 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4033 [(set_attr "type" "imul")])
4035 (define_expand "smulsi3_highpart"
4036 [(set (match_operand:SI 0 "register_operand" "")
4038 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4039 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4041 "TARGET_HARD_MUL && TARGET_ARCH32"
4043 if (CONSTANT_P (operands[2]))
4047 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4053 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4058 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4059 operands[2], GEN_INT (32)));
4065 (define_insn "smulsi3_highpart_v8plus"
4066 [(set (match_operand:SI 0 "register_operand" "=h,r")
4068 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4069 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4070 (match_operand:SI 3 "small_int_operand" "I,I"))))
4071 (clobber (match_scratch:SI 4 "=X,&h"))]
4074 smul\t%1, %2, %0\;srlx\t%0, %3, %0
4075 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4076 [(set_attr "type" "multi")
4077 (set_attr "length" "2")])
4079 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4082 [(set (match_operand:SI 0 "register_operand" "=h,r")
4085 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4086 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4087 (match_operand:SI 3 "small_int_operand" "I,I"))
4089 (clobber (match_scratch:SI 4 "=X,&h"))]
4092 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4093 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4094 [(set_attr "type" "multi")
4095 (set_attr "length" "2")])
4098 (define_insn "const_smulsi3_highpart_v8plus"
4099 [(set (match_operand:SI 0 "register_operand" "=h,r")
4101 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4102 (match_operand:DI 2 "small_int_operand" "I,I"))
4103 (match_operand:SI 3 "small_int_operand" "I,I"))))
4104 (clobber (match_scratch:SI 4 "=X,&h"))]
4107 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4108 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4109 [(set_attr "type" "multi")
4110 (set_attr "length" "2")])
4113 (define_insn "*smulsi3_highpart_sp32"
4114 [(set (match_operand:SI 0 "register_operand" "=r")
4116 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4117 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4120 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4121 [(set_attr "type" "multi")
4122 (set_attr "length" "2")])
4125 (define_insn "const_smulsi3_highpart"
4126 [(set (match_operand:SI 0 "register_operand" "=r")
4128 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4129 (match_operand:DI 2 "small_int_operand" "i"))
4132 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4133 [(set_attr "type" "multi")
4134 (set_attr "length" "2")])
4136 (define_expand "umulsidi3"
4137 [(set (match_operand:DI 0 "register_operand" "")
4138 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4139 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4142 if (CONSTANT_P (operands[2]))
4145 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4147 else if (TARGET_ARCH32)
4148 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4151 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4157 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4163 (define_insn "umulsidi3_v8plus"
4164 [(set (match_operand:DI 0 "register_operand" "=h,r")
4165 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4166 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4167 (clobber (match_scratch:SI 3 "=X,&h"))]
4170 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4171 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4172 [(set_attr "type" "multi")
4173 (set_attr "length" "2,3")])
4176 (define_insn "*umulsidi3_sp32"
4177 [(set (match_operand:DI 0 "register_operand" "=r")
4178 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4179 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4182 return TARGET_SPARCLET
4183 ? "umuld\t%1, %2, %L0"
4184 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4187 (if_then_else (eq_attr "isa" "sparclet")
4188 (const_string "imul") (const_string "multi")))
4189 (set (attr "length")
4190 (if_then_else (eq_attr "isa" "sparclet")
4191 (const_int 1) (const_int 2)))])
4193 (define_insn "*umulsidi3_sp64"
4194 [(set (match_operand:DI 0 "register_operand" "=r")
4195 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4196 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4197 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4199 [(set_attr "type" "imul")])
4201 ;; Extra pattern, because sign_extend of a constant isn't valid.
4204 (define_insn "const_umulsidi3_sp32"
4205 [(set (match_operand:DI 0 "register_operand" "=r")
4206 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4207 (match_operand:DI 2 "uns_small_int_operand" "")))]
4210 return TARGET_SPARCLET
4211 ? "umuld\t%1, %s2, %L0"
4212 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4215 (if_then_else (eq_attr "isa" "sparclet")
4216 (const_string "imul") (const_string "multi")))
4217 (set (attr "length")
4218 (if_then_else (eq_attr "isa" "sparclet")
4219 (const_int 1) (const_int 2)))])
4221 (define_insn "const_umulsidi3_sp64"
4222 [(set (match_operand:DI 0 "register_operand" "=r")
4223 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4224 (match_operand:DI 2 "uns_small_int_operand" "")))]
4225 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4227 [(set_attr "type" "imul")])
4230 (define_insn "const_umulsidi3_v8plus"
4231 [(set (match_operand:DI 0 "register_operand" "=h,r")
4232 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4233 (match_operand:DI 2 "uns_small_int_operand" "")))
4234 (clobber (match_scratch:SI 3 "=X,h"))]
4237 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4238 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4239 [(set_attr "type" "multi")
4240 (set_attr "length" "2,3")])
4242 (define_expand "umulsi3_highpart"
4243 [(set (match_operand:SI 0 "register_operand" "")
4245 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4246 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4248 "TARGET_HARD_MUL && TARGET_ARCH32"
4250 if (CONSTANT_P (operands[2]))
4254 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4260 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4265 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4266 operands[2], GEN_INT (32)));
4272 (define_insn "umulsi3_highpart_v8plus"
4273 [(set (match_operand:SI 0 "register_operand" "=h,r")
4275 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4276 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4277 (match_operand:SI 3 "small_int_operand" "I,I"))))
4278 (clobber (match_scratch:SI 4 "=X,h"))]
4281 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4282 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4283 [(set_attr "type" "multi")
4284 (set_attr "length" "2")])
4287 (define_insn "const_umulsi3_highpart_v8plus"
4288 [(set (match_operand:SI 0 "register_operand" "=h,r")
4290 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4291 (match_operand:DI 2 "uns_small_int_operand" ""))
4292 (match_operand:SI 3 "small_int_operand" "I,I"))))
4293 (clobber (match_scratch:SI 4 "=X,h"))]
4296 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4297 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4298 [(set_attr "type" "multi")
4299 (set_attr "length" "2")])
4302 (define_insn "*umulsi3_highpart_sp32"
4303 [(set (match_operand:SI 0 "register_operand" "=r")
4305 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4306 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4309 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4310 [(set_attr "type" "multi")
4311 (set_attr "length" "2")])
4314 (define_insn "const_umulsi3_highpart"
4315 [(set (match_operand:SI 0 "register_operand" "=r")
4317 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4318 (match_operand:DI 2 "uns_small_int_operand" ""))
4321 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4322 [(set_attr "type" "multi")
4323 (set_attr "length" "2")])
4325 (define_expand "divsi3"
4326 [(parallel [(set (match_operand:SI 0 "register_operand" "")
4327 (div:SI (match_operand:SI 1 "register_operand" "")
4328 (match_operand:SI 2 "input_operand" "")))
4329 (clobber (match_scratch:SI 3 ""))])]
4330 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4334 operands[3] = gen_reg_rtx(SImode);
4335 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4336 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4342 ;; The V8 architecture specifies that there must be at least 3 instructions
4343 ;; between a write to the Y register and a use of it for correct results.
4344 ;; We try to fill one of them with a simple constant or a memory load.
4346 (define_insn "divsi3_sp32"
4347 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4348 (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4349 (match_operand:SI 2 "input_operand" "rI,K,m")))
4350 (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4351 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4353 output_asm_insn ("sra\t%1, 31, %3", operands);
4354 output_asm_insn ("wr\t%3, 0, %%y", operands);
4356 switch (which_alternative)
4360 return "sdiv\t%1, %2, %0";
4362 return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4365 return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4367 return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4370 return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4372 return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4377 [(set_attr "type" "multi")
4378 (set (attr "length")
4379 (if_then_else (eq_attr "isa" "v9")
4380 (const_int 4) (const_int 6)))])
4382 (define_insn "divsi3_sp64"
4383 [(set (match_operand:SI 0 "register_operand" "=r")
4384 (div:SI (match_operand:SI 1 "register_operand" "r")
4385 (match_operand:SI 2 "input_operand" "rI")))
4386 (use (match_operand:SI 3 "register_operand" "r"))]
4387 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4388 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4389 [(set_attr "type" "multi")
4390 (set_attr "length" "2")])
4392 (define_insn "divdi3"
4393 [(set (match_operand:DI 0 "register_operand" "=r")
4394 (div:DI (match_operand:DI 1 "register_operand" "r")
4395 (match_operand:DI 2 "arith_operand" "rI")))]
4398 [(set_attr "type" "idiv")])
4400 (define_insn "*cmp_sdiv_cc_set"
4402 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4403 (match_operand:SI 2 "arith_operand" "rI"))
4405 (set (match_operand:SI 0 "register_operand" "=r")
4406 (div:SI (match_dup 1) (match_dup 2)))
4407 (clobber (match_scratch:SI 3 "=&r"))]
4408 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4410 output_asm_insn ("sra\t%1, 31, %3", operands);
4411 output_asm_insn ("wr\t%3, 0, %%y", operands);
4414 return "sdivcc\t%1, %2, %0";
4416 return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4418 [(set_attr "type" "multi")
4419 (set (attr "length")
4420 (if_then_else (eq_attr "isa" "v9")
4421 (const_int 3) (const_int 6)))])
4424 (define_expand "udivsi3"
4425 [(set (match_operand:SI 0 "register_operand" "")
4426 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4427 (match_operand:SI 2 "input_operand" "")))]
4428 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4431 ;; The V8 architecture specifies that there must be at least 3 instructions
4432 ;; between a write to the Y register and a use of it for correct results.
4433 ;; We try to fill one of them with a simple constant or a memory load.
4435 (define_insn "udivsi3_sp32"
4436 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
4437 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
4438 (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
4439 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4441 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4443 switch (which_alternative)
4447 return "udiv\t%1, %2, %0";
4449 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
4452 return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
4454 return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4457 return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
4459 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4462 return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
4464 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
4469 [(set_attr "type" "multi")
4470 (set (attr "length")
4471 (if_then_else (eq_attr "isa" "v9")
4472 (const_int 3) (const_int 5)))])
4474 (define_insn "udivsi3_sp64"
4475 [(set (match_operand:SI 0 "register_operand" "=r")
4476 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
4477 (match_operand:SI 2 "input_operand" "rI")))]
4478 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4479 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
4480 [(set_attr "type" "multi")
4481 (set_attr "length" "2")])
4483 (define_insn "udivdi3"
4484 [(set (match_operand:DI 0 "register_operand" "=r")
4485 (udiv:DI (match_operand:DI 1 "register_operand" "r")
4486 (match_operand:DI 2 "arith_operand" "rI")))]
4489 [(set_attr "type" "idiv")])
4491 (define_insn "*cmp_udiv_cc_set"
4493 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
4494 (match_operand:SI 2 "arith_operand" "rI"))
4496 (set (match_operand:SI 0 "register_operand" "=r")
4497 (udiv:SI (match_dup 1) (match_dup 2)))]
4498 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4500 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4503 return "udivcc\t%1, %2, %0";
4505 return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
4507 [(set_attr "type" "multi")
4508 (set (attr "length")
4509 (if_then_else (eq_attr "isa" "v9")
4510 (const_int 2) (const_int 5)))])
4512 ; sparclet multiply/accumulate insns
4514 (define_insn "*smacsi"
4515 [(set (match_operand:SI 0 "register_operand" "=r")
4516 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
4517 (match_operand:SI 2 "arith_operand" "rI"))
4518 (match_operand:SI 3 "register_operand" "0")))]
4521 [(set_attr "type" "imul")])
4523 (define_insn "*smacdi"
4524 [(set (match_operand:DI 0 "register_operand" "=r")
4525 (plus:DI (mult:DI (sign_extend:DI
4526 (match_operand:SI 1 "register_operand" "%r"))
4528 (match_operand:SI 2 "register_operand" "r")))
4529 (match_operand:DI 3 "register_operand" "0")))]
4531 "smacd\t%1, %2, %L0"
4532 [(set_attr "type" "imul")])
4534 (define_insn "*umacdi"
4535 [(set (match_operand:DI 0 "register_operand" "=r")
4536 (plus:DI (mult:DI (zero_extend:DI
4537 (match_operand:SI 1 "register_operand" "%r"))
4539 (match_operand:SI 2 "register_operand" "r")))
4540 (match_operand:DI 3 "register_operand" "0")))]
4542 "umacd\t%1, %2, %L0"
4543 [(set_attr "type" "imul")])
4546 ;; Boolean instructions.
4548 ;; We define DImode `and' so with DImode `not' we can get
4549 ;; DImode `andn'. Other combinations are possible.
4551 (define_expand "and<V64I:mode>3"
4552 [(set (match_operand:V64I 0 "register_operand" "")
4553 (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
4554 (match_operand:V64I 2 "arith_double_operand" "")))]
4558 (define_insn "*and<V64I:mode>3_sp32"
4559 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4560 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4561 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4566 [(set_attr "type" "*,fga")
4567 (set_attr "length" "2,*")
4568 (set_attr "fptype" "*,double")])
4570 (define_insn "*and<V64I:mode>3_sp64"
4571 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4572 (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4573 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4578 [(set_attr "type" "*,fga")
4579 (set_attr "fptype" "*,double")])
4581 (define_insn "and<V32I:mode>3"
4582 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4583 (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4584 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4589 [(set_attr "type" "*,fga")
4590 (set_attr "fptype" "*,single")])
4593 [(set (match_operand:SI 0 "register_operand" "")
4594 (and:SI (match_operand:SI 1 "register_operand" "")
4595 (match_operand:SI 2 "const_compl_high_operand" "")))
4596 (clobber (match_operand:SI 3 "register_operand" ""))]
4598 [(set (match_dup 3) (match_dup 4))
4599 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
4601 operands[4] = GEN_INT (~INTVAL (operands[2]));
4604 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
4605 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4606 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4607 (match_operand:V64I 2 "register_operand" "r,b")))]
4611 fandnot1\t%1, %2, %0"
4612 "&& reload_completed
4613 && ((GET_CODE (operands[0]) == REG
4614 && REGNO (operands[0]) < 32)
4615 || (GET_CODE (operands[0]) == SUBREG
4616 && GET_CODE (SUBREG_REG (operands[0])) == REG
4617 && REGNO (SUBREG_REG (operands[0])) < 32))"
4618 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
4619 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
4620 "operands[3] = gen_highpart (SImode, operands[0]);
4621 operands[4] = gen_highpart (SImode, operands[1]);
4622 operands[5] = gen_highpart (SImode, operands[2]);
4623 operands[6] = gen_lowpart (SImode, operands[0]);
4624 operands[7] = gen_lowpart (SImode, operands[1]);
4625 operands[8] = gen_lowpart (SImode, operands[2]);"
4626 [(set_attr "type" "*,fga")
4627 (set_attr "length" "2,*")
4628 (set_attr "fptype" "*,double")])
4630 (define_insn "*and_not_<V64I:mode>_sp64"
4631 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4632 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4633 (match_operand:V64I 2 "register_operand" "r,b")))]
4637 fandnot1\t%1, %2, %0"
4638 [(set_attr "type" "*,fga")
4639 (set_attr "fptype" "*,double")])
4641 (define_insn "*and_not_<V32I:mode>"
4642 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4643 (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
4644 (match_operand:V32I 2 "register_operand" "r,d")))]
4648 fandnot1s\t%1, %2, %0"
4649 [(set_attr "type" "*,fga")
4650 (set_attr "fptype" "*,single")])
4652 (define_expand "ior<V64I:mode>3"
4653 [(set (match_operand:V64I 0 "register_operand" "")
4654 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
4655 (match_operand:V64I 2 "arith_double_operand" "")))]
4659 (define_insn "*ior<V64I:mode>3_sp32"
4660 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4661 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4662 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4667 [(set_attr "type" "*,fga")
4668 (set_attr "length" "2,*")
4669 (set_attr "fptype" "*,double")])
4671 (define_insn "*ior<V64I:mode>3_sp64"
4672 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4673 (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4674 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4679 [(set_attr "type" "*,fga")
4680 (set_attr "fptype" "*,double")])
4682 (define_insn "ior<V32I:mode>3"
4683 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4684 (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4685 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4690 [(set_attr "type" "*,fga")
4691 (set_attr "fptype" "*,single")])
4694 [(set (match_operand:SI 0 "register_operand" "")
4695 (ior:SI (match_operand:SI 1 "register_operand" "")
4696 (match_operand:SI 2 "const_compl_high_operand" "")))
4697 (clobber (match_operand:SI 3 "register_operand" ""))]
4699 [(set (match_dup 3) (match_dup 4))
4700 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4702 operands[4] = GEN_INT (~INTVAL (operands[2]));
4705 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
4706 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4707 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4708 (match_operand:V64I 2 "register_operand" "r,b")))]
4712 fornot1\t%1, %2, %0"
4713 "&& reload_completed
4714 && ((GET_CODE (operands[0]) == REG
4715 && REGNO (operands[0]) < 32)
4716 || (GET_CODE (operands[0]) == SUBREG
4717 && GET_CODE (SUBREG_REG (operands[0])) == REG
4718 && REGNO (SUBREG_REG (operands[0])) < 32))"
4719 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
4720 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
4721 "operands[3] = gen_highpart (SImode, operands[0]);
4722 operands[4] = gen_highpart (SImode, operands[1]);
4723 operands[5] = gen_highpart (SImode, operands[2]);
4724 operands[6] = gen_lowpart (SImode, operands[0]);
4725 operands[7] = gen_lowpart (SImode, operands[1]);
4726 operands[8] = gen_lowpart (SImode, operands[2]);"
4727 [(set_attr "type" "*,fga")
4728 (set_attr "length" "2,*")
4729 (set_attr "fptype" "*,double")])
4731 (define_insn "*or_not_<V64I:mode>_sp64"
4732 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4733 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4734 (match_operand:V64I 2 "register_operand" "r,b")))]
4738 fornot1\t%1, %2, %0"
4739 [(set_attr "type" "*,fga")
4740 (set_attr "fptype" "*,double")])
4742 (define_insn "*or_not_<V32I:mode>"
4743 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4744 (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
4745 (match_operand:V32I 2 "register_operand" "r,d")))]
4749 fornot1s\t%1, %2, %0"
4750 [(set_attr "type" "*,fga")
4751 (set_attr "fptype" "*,single")])
4753 (define_expand "xor<V64I:mode>3"
4754 [(set (match_operand:V64I 0 "register_operand" "")
4755 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
4756 (match_operand:V64I 2 "arith_double_operand" "")))]
4760 (define_insn "*xor<V64I:mode>3_sp32"
4761 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4762 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4763 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4768 [(set_attr "type" "*,fga")
4769 (set_attr "length" "2,*")
4770 (set_attr "fptype" "*,double")])
4772 (define_insn "*xor<V64I:mode>3_sp64"
4773 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4774 (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
4775 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4780 [(set_attr "type" "*,fga")
4781 (set_attr "fptype" "*,double")])
4783 (define_insn "xor<V32I:mode>3"
4784 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4785 (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
4786 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4791 [(set_attr "type" "*,fga")
4792 (set_attr "fptype" "*,single")])
4795 [(set (match_operand:SI 0 "register_operand" "")
4796 (xor:SI (match_operand:SI 1 "register_operand" "")
4797 (match_operand:SI 2 "const_compl_high_operand" "")))
4798 (clobber (match_operand:SI 3 "register_operand" ""))]
4800 [(set (match_dup 3) (match_dup 4))
4801 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4803 operands[4] = GEN_INT (~INTVAL (operands[2]));
4807 [(set (match_operand:SI 0 "register_operand" "")
4808 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
4809 (match_operand:SI 2 "const_compl_high_operand" ""))))
4810 (clobber (match_operand:SI 3 "register_operand" ""))]
4812 [(set (match_dup 3) (match_dup 4))
4813 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
4815 operands[4] = GEN_INT (~INTVAL (operands[2]));
4818 ;; Split DImode logical operations requiring two instructions.
4820 [(set (match_operand:V64I 0 "register_operand" "")
4821 (match_operator:V64I 1 "cc_arith_operator" ; AND, IOR, XOR
4822 [(match_operand:V64I 2 "register_operand" "")
4823 (match_operand:V64I 3 "arith_double_operand" "")]))]
4826 && ((GET_CODE (operands[0]) == REG
4827 && REGNO (operands[0]) < 32)
4828 || (GET_CODE (operands[0]) == SUBREG
4829 && GET_CODE (SUBREG_REG (operands[0])) == REG
4830 && REGNO (SUBREG_REG (operands[0])) < 32))"
4831 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
4832 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
4834 operands[4] = gen_highpart (SImode, operands[0]);
4835 operands[5] = gen_lowpart (SImode, operands[0]);
4836 operands[6] = gen_highpart (SImode, operands[2]);
4837 operands[7] = gen_lowpart (SImode, operands[2]);
4838 #if HOST_BITS_PER_WIDE_INT == 32
4839 if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
4841 if (INTVAL (operands[3]) < 0)
4842 operands[8] = constm1_rtx;
4844 operands[8] = const0_rtx;
4848 operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
4849 operands[9] = gen_lowpart (SImode, operands[3]);
4852 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
4853 ;; Combine now canonicalizes to the rightmost expression.
4854 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
4855 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4856 (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
4857 (match_operand:V64I 2 "register_operand" "r,b"))))]
4862 "&& reload_completed
4863 && ((GET_CODE (operands[0]) == REG
4864 && REGNO (operands[0]) < 32)
4865 || (GET_CODE (operands[0]) == SUBREG
4866 && GET_CODE (SUBREG_REG (operands[0])) == REG
4867 && REGNO (SUBREG_REG (operands[0])) < 32))"
4868 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
4869 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
4870 "operands[3] = gen_highpart (SImode, operands[0]);
4871 operands[4] = gen_highpart (SImode, operands[1]);
4872 operands[5] = gen_highpart (SImode, operands[2]);
4873 operands[6] = gen_lowpart (SImode, operands[0]);
4874 operands[7] = gen_lowpart (SImode, operands[1]);
4875 operands[8] = gen_lowpart (SImode, operands[2]);"
4876 [(set_attr "type" "*,fga")
4877 (set_attr "length" "2,*")
4878 (set_attr "fptype" "*,double")])
4880 (define_insn "*xor_not_<V64I:mode>_sp64"
4881 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4882 (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
4883 (match_operand:V64I 2 "arith_operand" "rI,b"))))]
4888 [(set_attr "type" "*,fga")
4889 (set_attr "fptype" "*,double")])
4891 (define_insn "*xor_not_<V32I:mode>"
4892 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4893 (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
4894 (match_operand:V32I 2 "arith_operand" "rI,d"))))]
4899 [(set_attr "type" "*,fga")
4900 (set_attr "fptype" "*,single")])
4902 ;; These correspond to the above in the case where we also (or only)
4903 ;; want to set the condition code.
4905 (define_insn "*cmp_cc_arith_op"
4908 (match_operator:SI 2 "cc_arith_operator"
4909 [(match_operand:SI 0 "arith_operand" "%r")
4910 (match_operand:SI 1 "arith_operand" "rI")])
4913 "%A2cc\t%0, %1, %%g0"
4914 [(set_attr "type" "compare")])
4916 (define_insn "*cmp_ccx_arith_op"
4919 (match_operator:DI 2 "cc_arith_operator"
4920 [(match_operand:DI 0 "arith_operand" "%r")
4921 (match_operand:DI 1 "arith_operand" "rI")])
4924 "%A2cc\t%0, %1, %%g0"
4925 [(set_attr "type" "compare")])
4927 (define_insn "*cmp_cc_arith_op_set"
4930 (match_operator:SI 3 "cc_arith_operator"
4931 [(match_operand:SI 1 "arith_operand" "%r")
4932 (match_operand:SI 2 "arith_operand" "rI")])
4934 (set (match_operand:SI 0 "register_operand" "=r")
4935 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
4936 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
4938 [(set_attr "type" "compare")])
4940 (define_insn "*cmp_ccx_arith_op_set"
4943 (match_operator:DI 3 "cc_arith_operator"
4944 [(match_operand:DI 1 "arith_operand" "%r")
4945 (match_operand:DI 2 "arith_operand" "rI")])
4947 (set (match_operand:DI 0 "register_operand" "=r")
4948 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
4949 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
4951 [(set_attr "type" "compare")])
4953 (define_insn "*cmp_cc_xor_not"
4956 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
4957 (match_operand:SI 1 "arith_operand" "rI")))
4960 "xnorcc\t%r0, %1, %%g0"
4961 [(set_attr "type" "compare")])
4963 (define_insn "*cmp_ccx_xor_not"
4966 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
4967 (match_operand:DI 1 "arith_operand" "rI")))
4970 "xnorcc\t%r0, %1, %%g0"
4971 [(set_attr "type" "compare")])
4973 (define_insn "*cmp_cc_xor_not_set"
4976 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4977 (match_operand:SI 2 "arith_operand" "rI")))
4979 (set (match_operand:SI 0 "register_operand" "=r")
4980 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
4982 "xnorcc\t%r1, %2, %0"
4983 [(set_attr "type" "compare")])
4985 (define_insn "*cmp_ccx_xor_not_set"
4988 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
4989 (match_operand:DI 2 "arith_operand" "rI")))
4991 (set (match_operand:DI 0 "register_operand" "=r")
4992 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
4994 "xnorcc\t%r1, %2, %0"
4995 [(set_attr "type" "compare")])
4997 (define_insn "*cmp_cc_arith_op_not"
5000 (match_operator:SI 2 "cc_arith_not_operator"
5001 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5002 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5005 "%B2cc\t%r1, %0, %%g0"
5006 [(set_attr "type" "compare")])
5008 (define_insn "*cmp_ccx_arith_op_not"
5011 (match_operator:DI 2 "cc_arith_not_operator"
5012 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5013 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5016 "%B2cc\t%r1, %0, %%g0"
5017 [(set_attr "type" "compare")])
5019 (define_insn "*cmp_cc_arith_op_not_set"
5022 (match_operator:SI 3 "cc_arith_not_operator"
5023 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5024 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5026 (set (match_operand:SI 0 "register_operand" "=r")
5027 (match_operator:SI 4 "cc_arith_not_operator"
5028 [(not:SI (match_dup 1)) (match_dup 2)]))]
5029 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5030 "%B3cc\t%r2, %1, %0"
5031 [(set_attr "type" "compare")])
5033 (define_insn "*cmp_ccx_arith_op_not_set"
5036 (match_operator:DI 3 "cc_arith_not_operator"
5037 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5038 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5040 (set (match_operand:DI 0 "register_operand" "=r")
5041 (match_operator:DI 4 "cc_arith_not_operator"
5042 [(not:DI (match_dup 1)) (match_dup 2)]))]
5043 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5044 "%B3cc\t%r2, %1, %0"
5045 [(set_attr "type" "compare")])
5047 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5048 ;; does not know how to make it work for constants.
5050 (define_expand "negdi2"
5051 [(set (match_operand:DI 0 "register_operand" "=r")
5052 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5055 if (! TARGET_ARCH64)
5057 emit_insn (gen_rtx_PARALLEL
5060 gen_rtx_SET (VOIDmode, operand0,
5061 gen_rtx_NEG (DImode, operand1)),
5062 gen_rtx_CLOBBER (VOIDmode,
5063 gen_rtx_REG (CCmode,
5069 (define_insn_and_split "*negdi2_sp32"
5070 [(set (match_operand:DI 0 "register_operand" "=r")
5071 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5072 (clobber (reg:CC 100))]
5075 "&& reload_completed"
5076 [(parallel [(set (reg:CC_NOOV 100)
5077 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5079 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5080 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5081 (ltu:SI (reg:CC 100) (const_int 0))))]
5082 "operands[2] = gen_highpart (SImode, operands[0]);
5083 operands[3] = gen_highpart (SImode, operands[1]);
5084 operands[4] = gen_lowpart (SImode, operands[0]);
5085 operands[5] = gen_lowpart (SImode, operands[1]);"
5086 [(set_attr "length" "2")])
5088 (define_insn "*negdi2_sp64"
5089 [(set (match_operand:DI 0 "register_operand" "=r")
5090 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5092 "sub\t%%g0, %1, %0")
5094 (define_insn "negsi2"
5095 [(set (match_operand:SI 0 "register_operand" "=r")
5096 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5098 "sub\t%%g0, %1, %0")
5100 (define_insn "*cmp_cc_neg"
5101 [(set (reg:CC_NOOV 100)
5102 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5105 "subcc\t%%g0, %0, %%g0"
5106 [(set_attr "type" "compare")])
5108 (define_insn "*cmp_ccx_neg"
5109 [(set (reg:CCX_NOOV 100)
5110 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5113 "subcc\t%%g0, %0, %%g0"
5114 [(set_attr "type" "compare")])
5116 (define_insn "*cmp_cc_set_neg"
5117 [(set (reg:CC_NOOV 100)
5118 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5120 (set (match_operand:SI 0 "register_operand" "=r")
5121 (neg:SI (match_dup 1)))]
5123 "subcc\t%%g0, %1, %0"
5124 [(set_attr "type" "compare")])
5126 (define_insn "*cmp_ccx_set_neg"
5127 [(set (reg:CCX_NOOV 100)
5128 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5130 (set (match_operand:DI 0 "register_operand" "=r")
5131 (neg:DI (match_dup 1)))]
5133 "subcc\t%%g0, %1, %0"
5134 [(set_attr "type" "compare")])
5136 ;; We cannot use the "not" pseudo insn because the Sun assembler
5137 ;; does not know how to make it work for constants.
5138 (define_expand "one_cmpl<V64I:mode>2"
5139 [(set (match_operand:V64I 0 "register_operand" "")
5140 (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5144 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5145 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5146 (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5151 "&& reload_completed
5152 && ((GET_CODE (operands[0]) == REG
5153 && REGNO (operands[0]) < 32)
5154 || (GET_CODE (operands[0]) == SUBREG
5155 && GET_CODE (SUBREG_REG (operands[0])) == REG
5156 && REGNO (SUBREG_REG (operands[0])) < 32))"
5157 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5158 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5159 "operands[2] = gen_highpart (SImode, operands[0]);
5160 operands[3] = gen_highpart (SImode, operands[1]);
5161 operands[4] = gen_lowpart (SImode, operands[0]);
5162 operands[5] = gen_lowpart (SImode, operands[1]);"
5163 [(set_attr "type" "*,fga")
5164 (set_attr "length" "2,*")
5165 (set_attr "fptype" "*,double")])
5167 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5168 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5169 (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5174 [(set_attr "type" "*,fga")
5175 (set_attr "fptype" "*,double")])
5177 (define_insn "one_cmpl<V32I:mode>2"
5178 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5179 (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5184 [(set_attr "type" "*,fga")
5185 (set_attr "fptype" "*,single")])
5187 (define_insn "*cmp_cc_not"
5189 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5192 "xnorcc\t%%g0, %0, %%g0"
5193 [(set_attr "type" "compare")])
5195 (define_insn "*cmp_ccx_not"
5197 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5200 "xnorcc\t%%g0, %0, %%g0"
5201 [(set_attr "type" "compare")])
5203 (define_insn "*cmp_cc_set_not"
5205 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5207 (set (match_operand:SI 0 "register_operand" "=r")
5208 (not:SI (match_dup 1)))]
5210 "xnorcc\t%%g0, %1, %0"
5211 [(set_attr "type" "compare")])
5213 (define_insn "*cmp_ccx_set_not"
5215 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5217 (set (match_operand:DI 0 "register_operand" "=r")
5218 (not:DI (match_dup 1)))]
5220 "xnorcc\t%%g0, %1, %0"
5221 [(set_attr "type" "compare")])
5223 (define_insn "*cmp_cc_set"
5224 [(set (match_operand:SI 0 "register_operand" "=r")
5225 (match_operand:SI 1 "register_operand" "r"))
5227 (compare:CC (match_dup 1)
5231 [(set_attr "type" "compare")])
5233 (define_insn "*cmp_ccx_set64"
5234 [(set (match_operand:DI 0 "register_operand" "=r")
5235 (match_operand:DI 1 "register_operand" "r"))
5237 (compare:CCX (match_dup 1)
5241 [(set_attr "type" "compare")])
5244 ;; Floating point arithmetic instructions.
5246 (define_expand "addtf3"
5247 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5248 (plus:TF (match_operand:TF 1 "general_operand" "")
5249 (match_operand:TF 2 "general_operand" "")))]
5250 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5251 "emit_tfmode_binop (PLUS, operands); DONE;")
5253 (define_insn "*addtf3_hq"
5254 [(set (match_operand:TF 0 "register_operand" "=e")
5255 (plus:TF (match_operand:TF 1 "register_operand" "e")
5256 (match_operand:TF 2 "register_operand" "e")))]
5257 "TARGET_FPU && TARGET_HARD_QUAD"
5259 [(set_attr "type" "fp")])
5261 (define_insn "adddf3"
5262 [(set (match_operand:DF 0 "register_operand" "=e")
5263 (plus:DF (match_operand:DF 1 "register_operand" "e")
5264 (match_operand:DF 2 "register_operand" "e")))]
5267 [(set_attr "type" "fp")
5268 (set_attr "fptype" "double")])
5270 (define_insn "addsf3"
5271 [(set (match_operand:SF 0 "register_operand" "=f")
5272 (plus:SF (match_operand:SF 1 "register_operand" "f")
5273 (match_operand:SF 2 "register_operand" "f")))]
5276 [(set_attr "type" "fp")])
5278 (define_expand "subtf3"
5279 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5280 (minus:TF (match_operand:TF 1 "general_operand" "")
5281 (match_operand:TF 2 "general_operand" "")))]
5282 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5283 "emit_tfmode_binop (MINUS, operands); DONE;")
5285 (define_insn "*subtf3_hq"
5286 [(set (match_operand:TF 0 "register_operand" "=e")
5287 (minus:TF (match_operand:TF 1 "register_operand" "e")
5288 (match_operand:TF 2 "register_operand" "e")))]
5289 "TARGET_FPU && TARGET_HARD_QUAD"
5291 [(set_attr "type" "fp")])
5293 (define_insn "subdf3"
5294 [(set (match_operand:DF 0 "register_operand" "=e")
5295 (minus:DF (match_operand:DF 1 "register_operand" "e")
5296 (match_operand:DF 2 "register_operand" "e")))]
5299 [(set_attr "type" "fp")
5300 (set_attr "fptype" "double")])
5302 (define_insn "subsf3"
5303 [(set (match_operand:SF 0 "register_operand" "=f")
5304 (minus:SF (match_operand:SF 1 "register_operand" "f")
5305 (match_operand:SF 2 "register_operand" "f")))]
5308 [(set_attr "type" "fp")])
5310 (define_expand "multf3"
5311 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5312 (mult:TF (match_operand:TF 1 "general_operand" "")
5313 (match_operand:TF 2 "general_operand" "")))]
5314 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5315 "emit_tfmode_binop (MULT, operands); DONE;")
5317 (define_insn "*multf3_hq"
5318 [(set (match_operand:TF 0 "register_operand" "=e")
5319 (mult:TF (match_operand:TF 1 "register_operand" "e")
5320 (match_operand:TF 2 "register_operand" "e")))]
5321 "TARGET_FPU && TARGET_HARD_QUAD"
5323 [(set_attr "type" "fpmul")])
5325 (define_insn "muldf3"
5326 [(set (match_operand:DF 0 "register_operand" "=e")
5327 (mult:DF (match_operand:DF 1 "register_operand" "e")
5328 (match_operand:DF 2 "register_operand" "e")))]
5331 [(set_attr "type" "fpmul")
5332 (set_attr "fptype" "double")])
5334 (define_insn "mulsf3"
5335 [(set (match_operand:SF 0 "register_operand" "=f")
5336 (mult:SF (match_operand:SF 1 "register_operand" "f")
5337 (match_operand:SF 2 "register_operand" "f")))]
5340 [(set_attr "type" "fpmul")])
5342 (define_insn "*muldf3_extend"
5343 [(set (match_operand:DF 0 "register_operand" "=e")
5344 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5345 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5346 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
5347 "fsmuld\t%1, %2, %0"
5348 [(set_attr "type" "fpmul")
5349 (set_attr "fptype" "double")])
5351 (define_insn "*multf3_extend"
5352 [(set (match_operand:TF 0 "register_operand" "=e")
5353 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5354 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5355 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5356 "fdmulq\t%1, %2, %0"
5357 [(set_attr "type" "fpmul")])
5359 (define_expand "divtf3"
5360 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5361 (div:TF (match_operand:TF 1 "general_operand" "")
5362 (match_operand:TF 2 "general_operand" "")))]
5363 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5364 "emit_tfmode_binop (DIV, operands); DONE;")
5366 ;; don't have timing for quad-prec. divide.
5367 (define_insn "*divtf3_hq"
5368 [(set (match_operand:TF 0 "register_operand" "=e")
5369 (div:TF (match_operand:TF 1 "register_operand" "e")
5370 (match_operand:TF 2 "register_operand" "e")))]
5371 "TARGET_FPU && TARGET_HARD_QUAD"
5373 [(set_attr "type" "fpdivd")])
5375 (define_insn "divdf3"
5376 [(set (match_operand:DF 0 "register_operand" "=e")
5377 (div:DF (match_operand:DF 1 "register_operand" "e")
5378 (match_operand:DF 2 "register_operand" "e")))]
5381 [(set_attr "type" "fpdivd")
5382 (set_attr "fptype" "double")])
5384 (define_insn "divsf3"
5385 [(set (match_operand:SF 0 "register_operand" "=f")
5386 (div:SF (match_operand:SF 1 "register_operand" "f")
5387 (match_operand:SF 2 "register_operand" "f")))]
5390 [(set_attr "type" "fpdivs")])
5392 (define_expand "negtf2"
5393 [(set (match_operand:TF 0 "register_operand" "=e,e")
5394 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5398 (define_insn_and_split "*negtf2_notv9"
5399 [(set (match_operand:TF 0 "register_operand" "=e,e")
5400 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5401 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5407 "&& reload_completed
5408 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5409 [(set (match_dup 2) (neg:SF (match_dup 3)))
5410 (set (match_dup 4) (match_dup 5))
5411 (set (match_dup 6) (match_dup 7))]
5412 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5413 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5414 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5415 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5416 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5417 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5418 [(set_attr "type" "fpmove,*")
5419 (set_attr "length" "*,2")])
5421 (define_insn_and_split "*negtf2_v9"
5422 [(set (match_operand:TF 0 "register_operand" "=e,e")
5423 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5424 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5425 "TARGET_FPU && TARGET_V9"
5429 "&& reload_completed
5430 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5431 [(set (match_dup 2) (neg:DF (match_dup 3)))
5432 (set (match_dup 4) (match_dup 5))]
5433 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5434 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5435 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5436 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5437 [(set_attr "type" "fpmove,*")
5438 (set_attr "length" "*,2")
5439 (set_attr "fptype" "double")])
5441 (define_expand "negdf2"
5442 [(set (match_operand:DF 0 "register_operand" "")
5443 (neg:DF (match_operand:DF 1 "register_operand" "")))]
5447 (define_insn_and_split "*negdf2_notv9"
5448 [(set (match_operand:DF 0 "register_operand" "=e,e")
5449 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
5450 "TARGET_FPU && ! TARGET_V9"
5454 "&& reload_completed
5455 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5456 [(set (match_dup 2) (neg:SF (match_dup 3)))
5457 (set (match_dup 4) (match_dup 5))]
5458 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5459 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5460 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5461 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5462 [(set_attr "type" "fpmove,*")
5463 (set_attr "length" "*,2")])
5465 (define_insn "*negdf2_v9"
5466 [(set (match_operand:DF 0 "register_operand" "=e")
5467 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5468 "TARGET_FPU && TARGET_V9"
5470 [(set_attr "type" "fpmove")
5471 (set_attr "fptype" "double")])
5473 (define_insn "negsf2"
5474 [(set (match_operand:SF 0 "register_operand" "=f")
5475 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
5478 [(set_attr "type" "fpmove")])
5480 (define_expand "abstf2"
5481 [(set (match_operand:TF 0 "register_operand" "")
5482 (abs:TF (match_operand:TF 1 "register_operand" "")))]
5486 (define_insn_and_split "*abstf2_notv9"
5487 [(set (match_operand:TF 0 "register_operand" "=e,e")
5488 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5489 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5490 "TARGET_FPU && ! TARGET_V9"
5494 "&& reload_completed
5495 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5496 [(set (match_dup 2) (abs:SF (match_dup 3)))
5497 (set (match_dup 4) (match_dup 5))
5498 (set (match_dup 6) (match_dup 7))]
5499 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5500 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5501 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5502 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5503 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5504 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5505 [(set_attr "type" "fpmove,*")
5506 (set_attr "length" "*,2")])
5508 (define_insn "*abstf2_hq_v9"
5509 [(set (match_operand:TF 0 "register_operand" "=e,e")
5510 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5511 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
5515 [(set_attr "type" "fpmove")
5516 (set_attr "fptype" "double,*")])
5518 (define_insn_and_split "*abstf2_v9"
5519 [(set (match_operand:TF 0 "register_operand" "=e,e")
5520 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5521 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
5525 "&& reload_completed
5526 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5527 [(set (match_dup 2) (abs:DF (match_dup 3)))
5528 (set (match_dup 4) (match_dup 5))]
5529 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5530 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5531 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5532 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5533 [(set_attr "type" "fpmove,*")
5534 (set_attr "length" "*,2")
5535 (set_attr "fptype" "double,*")])
5537 (define_expand "absdf2"
5538 [(set (match_operand:DF 0 "register_operand" "")
5539 (abs:DF (match_operand:DF 1 "register_operand" "")))]
5543 (define_insn_and_split "*absdf2_notv9"
5544 [(set (match_operand:DF 0 "register_operand" "=e,e")
5545 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
5546 "TARGET_FPU && ! TARGET_V9"
5550 "&& reload_completed
5551 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5552 [(set (match_dup 2) (abs:SF (match_dup 3)))
5553 (set (match_dup 4) (match_dup 5))]
5554 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5555 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5556 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5557 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5558 [(set_attr "type" "fpmove,*")
5559 (set_attr "length" "*,2")])
5561 (define_insn "*absdf2_v9"
5562 [(set (match_operand:DF 0 "register_operand" "=e")
5563 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5564 "TARGET_FPU && TARGET_V9"
5566 [(set_attr "type" "fpmove")
5567 (set_attr "fptype" "double")])
5569 (define_insn "abssf2"
5570 [(set (match_operand:SF 0 "register_operand" "=f")
5571 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
5574 [(set_attr "type" "fpmove")])
5576 (define_expand "sqrttf2"
5577 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5578 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
5579 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5580 "emit_tfmode_unop (SQRT, operands); DONE;")
5582 (define_insn "*sqrttf2_hq"
5583 [(set (match_operand:TF 0 "register_operand" "=e")
5584 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
5585 "TARGET_FPU && TARGET_HARD_QUAD"
5587 [(set_attr "type" "fpsqrtd")])
5589 (define_insn "sqrtdf2"
5590 [(set (match_operand:DF 0 "register_operand" "=e")
5591 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5594 [(set_attr "type" "fpsqrtd")
5595 (set_attr "fptype" "double")])
5597 (define_insn "sqrtsf2"
5598 [(set (match_operand:SF 0 "register_operand" "=f")
5599 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
5602 [(set_attr "type" "fpsqrts")])
5605 ;; Arithmetic shift instructions.
5607 (define_insn "ashlsi3"
5608 [(set (match_operand:SI 0 "register_operand" "=r")
5609 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5610 (match_operand:SI 2 "arith_operand" "rI")))]
5613 if (GET_CODE (operands[2]) == CONST_INT)
5614 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5615 return "sll\t%1, %2, %0";
5618 (if_then_else (match_operand 2 "const_one_operand" "")
5619 (const_string "ialu") (const_string "shift")))])
5621 (define_expand "ashldi3"
5622 [(set (match_operand:DI 0 "register_operand" "=r")
5623 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5624 (match_operand:SI 2 "arith_operand" "rI")))]
5625 "TARGET_ARCH64 || TARGET_V8PLUS"
5627 if (! TARGET_ARCH64)
5629 if (GET_CODE (operands[2]) == CONST_INT)
5631 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
5636 (define_insn "*ashldi3_sp64"
5637 [(set (match_operand:DI 0 "register_operand" "=r")
5638 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5639 (match_operand:SI 2 "arith_operand" "rI")))]
5642 if (GET_CODE (operands[2]) == CONST_INT)
5643 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5644 return "sllx\t%1, %2, %0";
5647 (if_then_else (match_operand 2 "const_one_operand" "")
5648 (const_string "ialu") (const_string "shift")))])
5651 (define_insn "ashldi3_v8plus"
5652 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5653 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5654 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5655 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5657 "* return output_v8plus_shift (operands, insn, \"sllx\");"
5658 [(set_attr "type" "multi")
5659 (set_attr "length" "5,5,6")])
5661 ;; Optimize (1LL<<x)-1
5662 ;; XXX this also needs to be fixed to handle equal subregs
5663 ;; XXX first before we could re-enable it.
5665 ; [(set (match_operand:DI 0 "register_operand" "=h")
5666 ; (plus:DI (ashift:DI (const_int 1)
5667 ; (match_operand:SI 1 "arith_operand" "rI"))
5669 ; "0 && TARGET_V8PLUS"
5671 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
5672 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5673 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5675 ; [(set_attr "type" "multi")
5676 ; (set_attr "length" "4")])
5678 (define_insn "*cmp_cc_ashift_1"
5679 [(set (reg:CC_NOOV 100)
5680 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
5684 "addcc\t%0, %0, %%g0"
5685 [(set_attr "type" "compare")])
5687 (define_insn "*cmp_cc_set_ashift_1"
5688 [(set (reg:CC_NOOV 100)
5689 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
5692 (set (match_operand:SI 0 "register_operand" "=r")
5693 (ashift:SI (match_dup 1) (const_int 1)))]
5696 [(set_attr "type" "compare")])
5698 (define_insn "ashrsi3"
5699 [(set (match_operand:SI 0 "register_operand" "=r")
5700 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5701 (match_operand:SI 2 "arith_operand" "rI")))]
5704 if (GET_CODE (operands[2]) == CONST_INT)
5705 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5706 return "sra\t%1, %2, %0";
5708 [(set_attr "type" "shift")])
5710 (define_insn "*ashrsi3_extend"
5711 [(set (match_operand:DI 0 "register_operand" "=r")
5712 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5713 (match_operand:SI 2 "arith_operand" "r"))))]
5716 [(set_attr "type" "shift")])
5718 ;; This handles the case as above, but with constant shift instead of
5719 ;; register. Combiner "simplifies" it for us a little bit though.
5720 (define_insn "*ashrsi3_extend2"
5721 [(set (match_operand:DI 0 "register_operand" "=r")
5722 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5724 (match_operand:SI 2 "small_int_operand" "I")))]
5725 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
5727 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5728 return "sra\t%1, %2, %0";
5730 [(set_attr "type" "shift")])
5732 (define_expand "ashrdi3"
5733 [(set (match_operand:DI 0 "register_operand" "=r")
5734 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5735 (match_operand:SI 2 "arith_operand" "rI")))]
5736 "TARGET_ARCH64 || TARGET_V8PLUS"
5738 if (! TARGET_ARCH64)
5740 if (GET_CODE (operands[2]) == CONST_INT)
5741 FAIL; /* prefer generic code in this case */
5742 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
5747 (define_insn "*ashrdi3_sp64"
5748 [(set (match_operand:DI 0 "register_operand" "=r")
5749 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5750 (match_operand:SI 2 "arith_operand" "rI")))]
5754 if (GET_CODE (operands[2]) == CONST_INT)
5755 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5756 return "srax\t%1, %2, %0";
5758 [(set_attr "type" "shift")])
5761 (define_insn "ashrdi3_v8plus"
5762 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5763 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5764 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5765 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5767 "* return output_v8plus_shift (operands, insn, \"srax\");"
5768 [(set_attr "type" "multi")
5769 (set_attr "length" "5,5,6")])
5771 (define_insn "lshrsi3"
5772 [(set (match_operand:SI 0 "register_operand" "=r")
5773 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5774 (match_operand:SI 2 "arith_operand" "rI")))]
5777 if (GET_CODE (operands[2]) == CONST_INT)
5778 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5779 return "srl\t%1, %2, %0";
5781 [(set_attr "type" "shift")])
5783 ;; This handles the case where
5784 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
5785 ;; but combiner "simplifies" it for us.
5786 (define_insn "*lshrsi3_extend"
5787 [(set (match_operand:DI 0 "register_operand" "=r")
5788 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5789 (match_operand:SI 2 "arith_operand" "r")) 0)
5790 (match_operand 3 "const_int_operand" "")))]
5791 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
5793 [(set_attr "type" "shift")])
5795 ;; This handles the case where
5796 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
5797 ;; but combiner "simplifies" it for us.
5798 (define_insn "*lshrsi3_extend2"
5799 [(set (match_operand:DI 0 "register_operand" "=r")
5800 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5801 (match_operand 2 "small_int_operand" "I")
5803 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5805 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
5806 return "srl\t%1, %2, %0";
5808 [(set_attr "type" "shift")])
5810 (define_expand "lshrdi3"
5811 [(set (match_operand:DI 0 "register_operand" "=r")
5812 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5813 (match_operand:SI 2 "arith_operand" "rI")))]
5814 "TARGET_ARCH64 || TARGET_V8PLUS"
5816 if (! TARGET_ARCH64)
5818 if (GET_CODE (operands[2]) == CONST_INT)
5820 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
5825 (define_insn "*lshrdi3_sp64"
5826 [(set (match_operand:DI 0 "register_operand" "=r")
5827 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5828 (match_operand:SI 2 "arith_operand" "rI")))]
5831 if (GET_CODE (operands[2]) == CONST_INT)
5832 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5833 return "srlx\t%1, %2, %0";
5835 [(set_attr "type" "shift")])
5838 (define_insn "lshrdi3_v8plus"
5839 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5840 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5841 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5842 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5844 "* return output_v8plus_shift (operands, insn, \"srlx\");"
5845 [(set_attr "type" "multi")
5846 (set_attr "length" "5,5,6")])
5849 [(set (match_operand:SI 0 "register_operand" "=r")
5850 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5852 (match_operand:SI 2 "small_int_operand" "I")))]
5853 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5855 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
5856 return "srax\t%1, %2, %0";
5858 [(set_attr "type" "shift")])
5861 [(set (match_operand:SI 0 "register_operand" "=r")
5862 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5864 (match_operand:SI 2 "small_int_operand" "I")))]
5865 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5867 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
5868 return "srlx\t%1, %2, %0";
5870 [(set_attr "type" "shift")])
5873 [(set (match_operand:SI 0 "register_operand" "=r")
5874 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5875 (match_operand:SI 2 "small_int_operand" "I")) 4)
5876 (match_operand:SI 3 "small_int_operand" "I")))]
5878 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
5879 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
5880 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
5882 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
5884 return "srax\t%1, %2, %0";
5886 [(set_attr "type" "shift")])
5889 [(set (match_operand:SI 0 "register_operand" "=r")
5890 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5891 (match_operand:SI 2 "small_int_operand" "I")) 4)
5892 (match_operand:SI 3 "small_int_operand" "I")))]
5894 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
5895 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
5896 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
5898 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
5900 return "srlx\t%1, %2, %0";
5902 [(set_attr "type" "shift")])
5905 ;; Unconditional and other jump instructions.
5908 [(set (pc) (label_ref (match_operand 0 "" "")))]
5910 "* return output_ubranch (operands[0], 0, insn);"
5911 [(set_attr "type" "uncond_branch")])
5913 (define_expand "tablejump"
5914 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
5915 (use (label_ref (match_operand 1 "" "")))])]
5918 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
5920 /* In pic mode, our address differences are against the base of the
5921 table. Add that base value back in; CSE ought to be able to combine
5922 the two address loads. */
5926 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
5928 if (CASE_VECTOR_MODE != Pmode)
5929 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
5930 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
5931 operands[0] = memory_address (Pmode, tmp);
5935 (define_insn "*tablejump_sp32"
5936 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
5937 (use (label_ref (match_operand 1 "" "")))]
5940 [(set_attr "type" "uncond_branch")])
5942 (define_insn "*tablejump_sp64"
5943 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
5944 (use (label_ref (match_operand 1 "" "")))]
5947 [(set_attr "type" "uncond_branch")])
5950 ;; Jump to subroutine instructions.
5952 (define_expand "call"
5953 ;; Note that this expression is not used for generating RTL.
5954 ;; All the RTL is generated explicitly below.
5955 [(call (match_operand 0 "call_operand" "")
5956 (match_operand 3 "" "i"))]
5957 ;; operands[2] is next_arg_register
5958 ;; operands[3] is struct_value_size_rtx.
5963 gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
5965 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
5967 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
5969 /* This is really a PIC sequence. We want to represent
5970 it as a funny jump so its delay slots can be filled.
5972 ??? But if this really *is* a CALL, will not it clobber the
5973 call-clobbered registers? We lose this if it is a JUMP_INSN.
5974 Why cannot we have delay slots filled if it were a CALL? */
5976 /* We accept negative sizes for untyped calls. */
5977 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
5982 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
5984 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
5990 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
5991 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
5995 fn_rtx = operands[0];
5997 /* We accept negative sizes for untyped calls. */
5998 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
5999 sparc_emit_call_insn
6002 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6004 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6007 sparc_emit_call_insn
6010 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6011 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6019 ;; We can't use the same pattern for these two insns, because then registers
6020 ;; in the address may not be properly reloaded.
6022 (define_insn "*call_address_sp32"
6023 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6024 (match_operand 1 "" ""))
6025 (clobber (reg:SI 15))]
6026 ;;- Do not use operand 1 for most machines.
6029 [(set_attr "type" "call")])
6031 (define_insn "*call_symbolic_sp32"
6032 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6033 (match_operand 1 "" ""))
6034 (clobber (reg:SI 15))]
6035 ;;- Do not use operand 1 for most machines.
6038 [(set_attr "type" "call")])
6040 (define_insn "*call_address_sp64"
6041 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6042 (match_operand 1 "" ""))
6043 (clobber (reg:DI 15))]
6044 ;;- Do not use operand 1 for most machines.
6047 [(set_attr "type" "call")])
6049 (define_insn "*call_symbolic_sp64"
6050 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6051 (match_operand 1 "" ""))
6052 (clobber (reg:DI 15))]
6053 ;;- Do not use operand 1 for most machines.
6056 [(set_attr "type" "call")])
6058 ;; This is a call that wants a structure value.
6059 ;; There is no such critter for v9 (??? we may need one anyway).
6060 (define_insn "*call_address_struct_value_sp32"
6061 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6062 (match_operand 1 "" ""))
6063 (match_operand 2 "immediate_operand" "")
6064 (clobber (reg:SI 15))]
6065 ;;- Do not use operand 1 for most machines.
6066 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6068 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6069 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6071 [(set_attr "type" "call_no_delay_slot")
6072 (set_attr "length" "3")])
6074 ;; This is a call that wants a structure value.
6075 ;; There is no such critter for v9 (??? we may need one anyway).
6076 (define_insn "*call_symbolic_struct_value_sp32"
6077 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6078 (match_operand 1 "" ""))
6079 (match_operand 2 "immediate_operand" "")
6080 (clobber (reg:SI 15))]
6081 ;;- Do not use operand 1 for most machines.
6082 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6084 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6085 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6087 [(set_attr "type" "call_no_delay_slot")
6088 (set_attr "length" "3")])
6090 ;; This is a call that may want a structure value. This is used for
6092 (define_insn "*call_address_untyped_struct_value_sp32"
6093 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6094 (match_operand 1 "" ""))
6095 (match_operand 2 "immediate_operand" "")
6096 (clobber (reg:SI 15))]
6097 ;;- Do not use operand 1 for most machines.
6098 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6099 "call\t%a0, %1\n\t nop\n\tnop"
6100 [(set_attr "type" "call_no_delay_slot")
6101 (set_attr "length" "3")])
6103 ;; This is a call that may want a structure value. This is used for
6105 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6106 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6107 (match_operand 1 "" ""))
6108 (match_operand 2 "immediate_operand" "")
6109 (clobber (reg:SI 15))]
6110 ;;- Do not use operand 1 for most machines.
6111 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6112 "call\t%a0, %1\n\t nop\n\tnop"
6113 [(set_attr "type" "call_no_delay_slot")
6114 (set_attr "length" "3")])
6116 (define_expand "call_value"
6117 ;; Note that this expression is not used for generating RTL.
6118 ;; All the RTL is generated explicitly below.
6119 [(set (match_operand 0 "register_operand" "=rf")
6120 (call (match_operand 1 "" "")
6121 (match_operand 4 "" "")))]
6122 ;; operand 2 is stack_size_rtx
6123 ;; operand 3 is next_arg_register
6129 gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6131 fn_rtx = operands[1];
6134 gen_rtx_SET (VOIDmode, operands[0],
6135 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6136 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6138 sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6143 (define_insn "*call_value_address_sp32"
6144 [(set (match_operand 0 "" "=rf")
6145 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6146 (match_operand 2 "" "")))
6147 (clobber (reg:SI 15))]
6148 ;;- Do not use operand 2 for most machines.
6151 [(set_attr "type" "call")])
6153 (define_insn "*call_value_symbolic_sp32"
6154 [(set (match_operand 0 "" "=rf")
6155 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6156 (match_operand 2 "" "")))
6157 (clobber (reg:SI 15))]
6158 ;;- Do not use operand 2 for most machines.
6161 [(set_attr "type" "call")])
6163 (define_insn "*call_value_address_sp64"
6164 [(set (match_operand 0 "" "")
6165 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6166 (match_operand 2 "" "")))
6167 (clobber (reg:DI 15))]
6168 ;;- Do not use operand 2 for most machines.
6171 [(set_attr "type" "call")])
6173 (define_insn "*call_value_symbolic_sp64"
6174 [(set (match_operand 0 "" "")
6175 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6176 (match_operand 2 "" "")))
6177 (clobber (reg:DI 15))]
6178 ;;- Do not use operand 2 for most machines.
6181 [(set_attr "type" "call")])
6183 (define_expand "untyped_call"
6184 [(parallel [(call (match_operand 0 "" "")
6186 (match_operand:BLK 1 "memory_operand" "")
6187 (match_operand 2 "" "")])]
6190 rtx valreg1 = gen_rtx_REG (DImode, 8);
6191 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6192 rtx result = operands[1];
6194 /* Pass constm1 to indicate that it may expect a structure value, but
6195 we don't know what size it is. */
6196 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6198 /* Save the function value registers. */
6199 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6200 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6203 /* The optimizer does not know that the call sets the function value
6204 registers we stored in the result block. We avoid problems by
6205 claiming that all hard registers are used and clobbered at this
6207 emit_insn (gen_blockage ());
6212 ;; Tail call instructions.
6214 (define_expand "sibcall"
6215 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6220 (define_insn "*sibcall_symbolic_sp32"
6221 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6222 (match_operand 1 "" ""))
6225 "* return output_sibcall(insn, operands[0]);"
6226 [(set_attr "type" "sibcall")])
6228 (define_insn "*sibcall_symbolic_sp64"
6229 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6230 (match_operand 1 "" ""))
6233 "* return output_sibcall(insn, operands[0]);"
6234 [(set_attr "type" "sibcall")])
6236 (define_expand "sibcall_value"
6237 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6238 (call (match_operand 1 "" "") (const_int 0)))
6243 (define_insn "*sibcall_value_symbolic_sp32"
6244 [(set (match_operand 0 "" "=rf")
6245 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6246 (match_operand 2 "" "")))
6249 "* return output_sibcall(insn, operands[1]);"
6250 [(set_attr "type" "sibcall")])
6252 (define_insn "*sibcall_value_symbolic_sp64"
6253 [(set (match_operand 0 "" "")
6254 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6255 (match_operand 2 "" "")))
6258 "* return output_sibcall(insn, operands[1]);"
6259 [(set_attr "type" "sibcall")])
6262 ;; Special instructions.
6264 (define_expand "prologue"
6268 sparc_expand_prologue ();
6272 ;; The "save register window" insn is modelled as follows so that the DWARF-2
6273 ;; backend automatically emits the required call frame debugging information
6274 ;; while it is parsing it. Therefore, the pattern should not be modified
6275 ;; without first studying the impact of the changes on the debug info.
6276 ;; [(set (%fp) (%sp))
6277 ;; (set (%sp) (unspec_volatile [(%sp) (-frame_size)] UNSPECV_SAVEW))
6278 ;; (set (%i7) (%o7))]
6280 (define_insn "save_register_window<P:mode>"
6281 [(set (reg:P 30) (reg:P 14))
6282 (set (reg:P 14) (unspec_volatile:P [(reg:P 14)
6283 (match_operand:P 0 "arith_operand" "rI")] UNSPECV_SAVEW))
6284 (set (reg:P 31) (reg:P 15))]
6286 "save\t%%sp, %0, %%sp"
6287 [(set_attr "type" "savew")])
6289 (define_expand "epilogue"
6293 sparc_expand_epilogue ();
6296 (define_expand "sibcall_epilogue"
6300 sparc_expand_epilogue ();
6304 (define_expand "return"
6306 "sparc_can_use_return_insn_p ()"
6309 (define_insn "*return_internal"
6312 "* return output_return (insn);"
6313 [(set_attr "type" "return")
6314 (set (attr "length")
6315 (cond [(eq_attr "leaf_function" "true")
6316 (if_then_else (eq_attr "empty_delay_slot" "true")
6319 (eq_attr "calls_eh_return" "true")
6320 (if_then_else (eq_attr "delayed_branch" "true")
6321 (if_then_else (eq_attr "isa" "v9")
6324 (if_then_else (eq_attr "isa" "v9")
6327 (eq_attr "empty_delay_slot" "true")
6328 (if_then_else (eq_attr "delayed_branch" "true")
6333 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6334 ;; all of memory. This blocks insns from being moved across this point.
6336 (define_insn "blockage"
6337 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6340 [(set_attr "length" "0")])
6342 (define_expand "probe_stack"
6343 [(set (match_operand 0 "memory_operand" "") (const_int 0))]
6347 = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
6350 (define_insn "probe_stack_range<P:mode>"
6351 [(set (match_operand:P 0 "register_operand" "=r")
6352 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6353 (match_operand:P 2 "register_operand" "r")]
6354 UNSPECV_PROBE_STACK_RANGE))]
6356 "* return output_probe_stack_range (operands[0], operands[2]);"
6357 [(set_attr "type" "multi")])
6359 ;; Prepare to return any type including a structure value.
6361 (define_expand "untyped_return"
6362 [(match_operand:BLK 0 "memory_operand" "")
6363 (match_operand 1 "" "")]
6366 rtx valreg1 = gen_rtx_REG (DImode, 24);
6367 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6368 rtx result = operands[0];
6370 if (! TARGET_ARCH64)
6372 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
6374 rtx value = gen_reg_rtx (SImode);
6376 /* Fetch the instruction where we will return to and see if it's an unimp
6377 instruction (the most significant 10 bits will be zero). If so,
6378 update the return address to skip the unimp instruction. */
6379 emit_move_insn (value,
6380 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
6381 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6382 emit_insn (gen_update_return (rtnreg, value));
6385 /* Reload the function value registers. */
6386 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6387 emit_move_insn (valreg2,
6388 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6390 /* Put USE insns before the return. */
6394 /* Construct the return. */
6395 expand_naked_return ();
6400 ;; Adjust the return address conditionally. If the value of op1 is equal
6401 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6402 ;; This is technically *half* the check required by the 32-bit SPARC
6403 ;; psABI. This check only ensures that an "unimp" insn was written by
6404 ;; the caller, but doesn't check to see if the expected size matches
6405 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6406 ;; only used by the above code "untyped_return".
6408 (define_insn "update_return"
6409 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6410 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6413 if (flag_delayed_branch)
6414 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6416 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6418 [(set (attr "type") (const_string "multi"))
6419 (set (attr "length")
6420 (if_then_else (eq_attr "delayed_branch" "true")
6429 (define_expand "indirect_jump"
6430 [(set (pc) (match_operand 0 "address_operand" "p"))]
6434 (define_insn "*branch_sp32"
6435 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6438 [(set_attr "type" "uncond_branch")])
6440 (define_insn "*branch_sp64"
6441 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6444 [(set_attr "type" "uncond_branch")])
6446 (define_expand "save_stack_nonlocal"
6447 [(set (match_operand 0 "memory_operand" "")
6448 (match_operand 1 "register_operand" ""))
6449 (set (match_dup 2) (match_dup 3))]
6452 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
6453 operands[2] = adjust_address_nv (operands[0], Pmode, GET_MODE_SIZE (Pmode));
6454 operands[3] = gen_rtx_REG (Pmode, 31); /* %i7 */
6457 (define_expand "restore_stack_nonlocal"
6458 [(set (match_operand 0 "register_operand" "")
6459 (match_operand 1 "memory_operand" ""))]
6462 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
6465 (define_expand "nonlocal_goto"
6466 [(match_operand 0 "general_operand" "")
6467 (match_operand 1 "general_operand" "")
6468 (match_operand 2 "memory_operand" "")
6469 (match_operand 3 "memory_operand" "")]
6472 rtx r_label = copy_to_reg (operands[1]);
6473 rtx r_sp = adjust_address_nv (operands[2], Pmode, 0);
6474 rtx r_fp = operands[3];
6475 rtx r_i7 = adjust_address_nv (operands[2], Pmode, GET_MODE_SIZE (Pmode));
6477 /* We need to flush all the register windows so that their contents will
6478 be re-synchronized by the restore insn of the target function. */
6479 emit_insn (gen_flush_register_windows ());
6481 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
6482 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
6484 /* Restore frame pointer for containing function. */
6485 emit_move_insn (hard_frame_pointer_rtx, r_fp);
6486 emit_stack_restore (SAVE_NONLOCAL, r_sp);
6488 /* USE of hard_frame_pointer_rtx added for consistency;
6489 not clear if really needed. */
6490 emit_use (hard_frame_pointer_rtx);
6491 emit_use (stack_pointer_rtx);
6493 /* We need to smuggle the load of %i7 as it is a fixed register. */
6494 emit_jump_insn (gen_nonlocal_goto_internal (r_label, r_i7));
6499 (define_insn "nonlocal_goto_internal"
6500 [(unspec_volatile [(match_operand 0 "register_operand" "r")
6501 (match_operand 1 "memory_operand" "m")] UNSPECV_GOTO)]
6502 "GET_MODE (operands[0]) == Pmode && GET_MODE (operands[1]) == Pmode"
6504 if (flag_delayed_branch)
6507 return "jmp\t%0\n\t ldx\t%1, %%i7";
6509 return "jmp\t%0\n\t ld\t%1, %%i7";
6514 return "ldx\t%1, %%i7\n\tjmp\t%0\n\t nop";
6516 return "ld\t%1, %%i7\n\tjmp\t%0\n\t nop";
6519 [(set (attr "type") (const_string "multi"))
6520 (set (attr "length")
6521 (if_then_else (eq_attr "delayed_branch" "true")
6525 (define_expand "builtin_setjmp_receiver"
6526 [(label_ref (match_operand 0 "" ""))]
6529 load_got_register ();
6533 ;; Special insn to flush register windows.
6535 (define_insn "flush_register_windows"
6536 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
6538 { return TARGET_V9 ? "flushw" : "ta\t3"; }
6539 [(set_attr "type" "flushw")])
6541 ;; Special pattern for the FLUSH instruction.
6543 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
6544 ; of the define_insn otherwise missing a mode. We make "flush", aka
6545 ; gen_flush, the default one since sparc_initialize_trampoline uses
6546 ; it on SImode mem values.
6548 (define_insn "flush"
6549 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6551 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6552 [(set_attr "type" "iflush")])
6554 (define_insn "flushdi"
6555 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6557 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6558 [(set_attr "type" "iflush")])
6561 ;; Find first set instructions.
6563 ;; The scan instruction searches from the most significant bit while ffs
6564 ;; searches from the least significant bit. The bit index and treatment of
6565 ;; zero also differ. It takes at least 7 instructions to get the proper
6566 ;; result. Here is an obvious 8 instruction sequence.
6569 (define_insn "ffssi2"
6570 [(set (match_operand:SI 0 "register_operand" "=&r")
6571 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
6572 (clobber (match_scratch:SI 2 "=&r"))]
6573 "TARGET_SPARCLITE || TARGET_SPARCLET"
6575 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";
6577 [(set_attr "type" "multi")
6578 (set_attr "length" "8")])
6580 ;; ??? This should be a define expand, so that the extra instruction have
6581 ;; a chance of being optimized away.
6583 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
6584 ;; does, but no one uses that and we don't have a switch for it.
6586 ;(define_insn "ffsdi2"
6587 ; [(set (match_operand:DI 0 "register_operand" "=&r")
6588 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
6589 ; (clobber (match_scratch:DI 2 "=&r"))]
6591 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
6592 ; [(set_attr "type" "multi")
6593 ; (set_attr "length" "4")])
6597 ;; Peepholes go at the end.
6599 ;; Optimize consecutive loads or stores into ldd and std when possible.
6600 ;; The conditions in which we do this are very restricted and are
6601 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
6604 [(set (match_operand:SI 0 "memory_operand" "")
6606 (set (match_operand:SI 1 "memory_operand" "")
6609 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
6612 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
6615 [(set (match_operand:SI 0 "memory_operand" "")
6617 (set (match_operand:SI 1 "memory_operand" "")
6620 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
6623 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
6626 [(set (match_operand:SI 0 "register_operand" "")
6627 (match_operand:SI 1 "memory_operand" ""))
6628 (set (match_operand:SI 2 "register_operand" "")
6629 (match_operand:SI 3 "memory_operand" ""))]
6630 "registers_ok_for_ldd_peep (operands[0], operands[2])
6631 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6634 "operands[1] = widen_memory_access (operands[1], DImode, 0);
6635 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
6638 [(set (match_operand:SI 0 "memory_operand" "")
6639 (match_operand:SI 1 "register_operand" ""))
6640 (set (match_operand:SI 2 "memory_operand" "")
6641 (match_operand:SI 3 "register_operand" ""))]
6642 "registers_ok_for_ldd_peep (operands[1], operands[3])
6643 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6646 "operands[0] = widen_memory_access (operands[0], DImode, 0);
6647 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
6650 [(set (match_operand:SF 0 "register_operand" "")
6651 (match_operand:SF 1 "memory_operand" ""))
6652 (set (match_operand:SF 2 "register_operand" "")
6653 (match_operand:SF 3 "memory_operand" ""))]
6654 "registers_ok_for_ldd_peep (operands[0], operands[2])
6655 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6658 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
6659 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
6662 [(set (match_operand:SF 0 "memory_operand" "")
6663 (match_operand:SF 1 "register_operand" ""))
6664 (set (match_operand:SF 2 "memory_operand" "")
6665 (match_operand:SF 3 "register_operand" ""))]
6666 "registers_ok_for_ldd_peep (operands[1], operands[3])
6667 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6670 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
6671 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
6674 [(set (match_operand:SI 0 "register_operand" "")
6675 (match_operand:SI 1 "memory_operand" ""))
6676 (set (match_operand:SI 2 "register_operand" "")
6677 (match_operand:SI 3 "memory_operand" ""))]
6678 "registers_ok_for_ldd_peep (operands[2], operands[0])
6679 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6682 "operands[3] = widen_memory_access (operands[3], DImode, 0);
6683 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
6686 [(set (match_operand:SI 0 "memory_operand" "")
6687 (match_operand:SI 1 "register_operand" ""))
6688 (set (match_operand:SI 2 "memory_operand" "")
6689 (match_operand:SI 3 "register_operand" ""))]
6690 "registers_ok_for_ldd_peep (operands[3], operands[1])
6691 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6694 "operands[2] = widen_memory_access (operands[2], DImode, 0);
6695 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
6699 [(set (match_operand:SF 0 "register_operand" "")
6700 (match_operand:SF 1 "memory_operand" ""))
6701 (set (match_operand:SF 2 "register_operand" "")
6702 (match_operand:SF 3 "memory_operand" ""))]
6703 "registers_ok_for_ldd_peep (operands[2], operands[0])
6704 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6707 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
6708 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
6711 [(set (match_operand:SF 0 "memory_operand" "")
6712 (match_operand:SF 1 "register_operand" ""))
6713 (set (match_operand:SF 2 "memory_operand" "")
6714 (match_operand:SF 3 "register_operand" ""))]
6715 "registers_ok_for_ldd_peep (operands[3], operands[1])
6716 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6719 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
6720 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
6722 ;; Optimize the case of following a reg-reg move with a test
6723 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
6724 ;; This can result from a float to fix conversion.
6727 [(set (match_operand:SI 0 "register_operand" "")
6728 (match_operand:SI 1 "register_operand" ""))
6730 (compare:CC (match_operand:SI 2 "register_operand" "")
6732 "(rtx_equal_p (operands[2], operands[0])
6733 || rtx_equal_p (operands[2], operands[1]))
6734 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6735 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6736 [(parallel [(set (match_dup 0) (match_dup 1))
6738 (compare:CC (match_dup 1) (const_int 0)))])]
6742 [(set (match_operand:DI 0 "register_operand" "")
6743 (match_operand:DI 1 "register_operand" ""))
6745 (compare:CCX (match_operand:DI 2 "register_operand" "")
6748 && (rtx_equal_p (operands[2], operands[0])
6749 || rtx_equal_p (operands[2], operands[1]))
6750 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6751 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6752 [(parallel [(set (match_dup 0) (match_dup 1))
6754 (compare:CCX (match_dup 1) (const_int 0)))])]
6758 ;; Prefetch instructions.
6760 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
6761 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
6762 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
6764 (define_expand "prefetch"
6765 [(match_operand 0 "address_operand" "")
6766 (match_operand 1 "const_int_operand" "")
6767 (match_operand 2 "const_int_operand" "")]
6771 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
6773 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
6777 (define_insn "prefetch_64"
6778 [(prefetch (match_operand:DI 0 "address_operand" "p")
6779 (match_operand:DI 1 "const_int_operand" "n")
6780 (match_operand:DI 2 "const_int_operand" "n"))]
6783 static const char * const prefetch_instr[2][2] = {
6785 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
6786 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
6789 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
6790 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
6793 int read_or_write = INTVAL (operands[1]);
6794 int locality = INTVAL (operands[2]);
6796 gcc_assert (read_or_write == 0 || read_or_write == 1);
6797 gcc_assert (locality >= 0 && locality < 4);
6798 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
6800 [(set_attr "type" "load")])
6802 (define_insn "prefetch_32"
6803 [(prefetch (match_operand:SI 0 "address_operand" "p")
6804 (match_operand:SI 1 "const_int_operand" "n")
6805 (match_operand:SI 2 "const_int_operand" "n"))]
6808 static const char * const prefetch_instr[2][2] = {
6810 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
6811 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
6814 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
6815 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
6818 int read_or_write = INTVAL (operands[1]);
6819 int locality = INTVAL (operands[2]);
6821 gcc_assert (read_or_write == 0 || read_or_write == 1);
6822 gcc_assert (locality >= 0 && locality < 4);
6823 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
6825 [(set_attr "type" "load")])
6828 ;; Trap instructions.
6831 [(trap_if (const_int 1) (const_int 5))]
6834 [(set_attr "type" "trap")])
6836 (define_expand "ctrapsi4"
6837 [(trap_if (match_operator 0 "noov_compare_operator"
6838 [(match_operand:SI 1 "compare_operand" "")
6839 (match_operand:SI 2 "arith_operand" "")])
6840 (match_operand 3 ""))]
6842 "operands[1] = gen_compare_reg (operands[0]);
6843 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
6845 operands[2] = const0_rtx;")
6847 (define_expand "ctrapdi4"
6848 [(trap_if (match_operator 0 "noov_compare_operator"
6849 [(match_operand:DI 1 "compare_operand" "")
6850 (match_operand:DI 2 "arith_operand" "")])
6851 (match_operand 3 ""))]
6853 "operands[1] = gen_compare_reg (operands[0]);
6854 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
6856 operands[2] = const0_rtx;")
6860 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC 100) (const_int 0)])
6861 (match_operand:SI 1 "arith_operand" "rM"))]
6865 return "t%C0\t%%icc, %1";
6869 [(set_attr "type" "trap")])
6872 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX 100) (const_int 0)])
6873 (match_operand:SI 1 "arith_operand" "rM"))]
6876 [(set_attr "type" "trap")])
6879 ;; TLS support instructions.
6881 (define_insn "tgd_hi22"
6882 [(set (match_operand:SI 0 "register_operand" "=r")
6883 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
6886 "sethi\\t%%tgd_hi22(%a1), %0")
6888 (define_insn "tgd_lo10"
6889 [(set (match_operand:SI 0 "register_operand" "=r")
6890 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
6891 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
6894 "add\\t%1, %%tgd_lo10(%a2), %0")
6896 (define_insn "tgd_add32"
6897 [(set (match_operand:SI 0 "register_operand" "=r")
6898 (plus:SI (match_operand:SI 1 "register_operand" "r")
6899 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
6900 (match_operand 3 "tgd_symbolic_operand" "")]
6902 "TARGET_TLS && TARGET_ARCH32"
6903 "add\\t%1, %2, %0, %%tgd_add(%a3)")
6905 (define_insn "tgd_add64"
6906 [(set (match_operand:DI 0 "register_operand" "=r")
6907 (plus:DI (match_operand:DI 1 "register_operand" "r")
6908 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
6909 (match_operand 3 "tgd_symbolic_operand" "")]
6911 "TARGET_TLS && TARGET_ARCH64"
6912 "add\\t%1, %2, %0, %%tgd_add(%a3)")
6914 (define_insn "tgd_call32"
6915 [(set (match_operand 0 "register_operand" "=r")
6916 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
6917 (match_operand 2 "tgd_symbolic_operand" "")]
6919 (match_operand 3 "" "")))
6920 (clobber (reg:SI 15))]
6921 "TARGET_TLS && TARGET_ARCH32"
6922 "call\t%a1, %%tgd_call(%a2)%#"
6923 [(set_attr "type" "call")])
6925 (define_insn "tgd_call64"
6926 [(set (match_operand 0 "register_operand" "=r")
6927 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
6928 (match_operand 2 "tgd_symbolic_operand" "")]
6930 (match_operand 3 "" "")))
6931 (clobber (reg:DI 15))]
6932 "TARGET_TLS && TARGET_ARCH64"
6933 "call\t%a1, %%tgd_call(%a2)%#"
6934 [(set_attr "type" "call")])
6936 (define_insn "tldm_hi22"
6937 [(set (match_operand:SI 0 "register_operand" "=r")
6938 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
6940 "sethi\\t%%tldm_hi22(%&), %0")
6942 (define_insn "tldm_lo10"
6943 [(set (match_operand:SI 0 "register_operand" "=r")
6944 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
6945 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
6947 "add\\t%1, %%tldm_lo10(%&), %0")
6949 (define_insn "tldm_add32"
6950 [(set (match_operand:SI 0 "register_operand" "=r")
6951 (plus:SI (match_operand:SI 1 "register_operand" "r")
6952 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
6954 "TARGET_TLS && TARGET_ARCH32"
6955 "add\\t%1, %2, %0, %%tldm_add(%&)")
6957 (define_insn "tldm_add64"
6958 [(set (match_operand:DI 0 "register_operand" "=r")
6959 (plus:DI (match_operand:DI 1 "register_operand" "r")
6960 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
6962 "TARGET_TLS && TARGET_ARCH64"
6963 "add\\t%1, %2, %0, %%tldm_add(%&)")
6965 (define_insn "tldm_call32"
6966 [(set (match_operand 0 "register_operand" "=r")
6967 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
6969 (match_operand 2 "" "")))
6970 (clobber (reg:SI 15))]
6971 "TARGET_TLS && TARGET_ARCH32"
6972 "call\t%a1, %%tldm_call(%&)%#"
6973 [(set_attr "type" "call")])
6975 (define_insn "tldm_call64"
6976 [(set (match_operand 0 "register_operand" "=r")
6977 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
6979 (match_operand 2 "" "")))
6980 (clobber (reg:DI 15))]
6981 "TARGET_TLS && TARGET_ARCH64"
6982 "call\t%a1, %%tldm_call(%&)%#"
6983 [(set_attr "type" "call")])
6985 (define_insn "tldo_hix22"
6986 [(set (match_operand:SI 0 "register_operand" "=r")
6987 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
6990 "sethi\\t%%tldo_hix22(%a1), %0")
6992 (define_insn "tldo_lox10"
6993 [(set (match_operand:SI 0 "register_operand" "=r")
6994 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
6995 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
6998 "xor\\t%1, %%tldo_lox10(%a2), %0")
7000 (define_insn "tldo_add32"
7001 [(set (match_operand:SI 0 "register_operand" "=r")
7002 (plus:SI (match_operand:SI 1 "register_operand" "r")
7003 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7004 (match_operand 3 "tld_symbolic_operand" "")]
7006 "TARGET_TLS && TARGET_ARCH32"
7007 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7009 (define_insn "tldo_add64"
7010 [(set (match_operand:DI 0 "register_operand" "=r")
7011 (plus:DI (match_operand:DI 1 "register_operand" "r")
7012 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7013 (match_operand 3 "tld_symbolic_operand" "")]
7015 "TARGET_TLS && TARGET_ARCH64"
7016 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7018 (define_insn "tie_hi22"
7019 [(set (match_operand:SI 0 "register_operand" "=r")
7020 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7023 "sethi\\t%%tie_hi22(%a1), %0")
7025 (define_insn "tie_lo10"
7026 [(set (match_operand:SI 0 "register_operand" "=r")
7027 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7028 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7031 "add\\t%1, %%tie_lo10(%a2), %0")
7033 (define_insn "tie_ld32"
7034 [(set (match_operand:SI 0 "register_operand" "=r")
7035 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7036 (match_operand:SI 2 "register_operand" "r")
7037 (match_operand 3 "tie_symbolic_operand" "")]
7039 "TARGET_TLS && TARGET_ARCH32"
7040 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7041 [(set_attr "type" "load")])
7043 (define_insn "tie_ld64"
7044 [(set (match_operand:DI 0 "register_operand" "=r")
7045 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7046 (match_operand:SI 2 "register_operand" "r")
7047 (match_operand 3 "tie_symbolic_operand" "")]
7049 "TARGET_TLS && TARGET_ARCH64"
7050 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7051 [(set_attr "type" "load")])
7053 (define_insn "tie_add32"
7054 [(set (match_operand:SI 0 "register_operand" "=r")
7055 (plus:SI (match_operand:SI 1 "register_operand" "r")
7056 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7057 (match_operand 3 "tie_symbolic_operand" "")]
7059 "TARGET_SUN_TLS && TARGET_ARCH32"
7060 "add\\t%1, %2, %0, %%tie_add(%a3)")
7062 (define_insn "tie_add64"
7063 [(set (match_operand:DI 0 "register_operand" "=r")
7064 (plus:DI (match_operand:DI 1 "register_operand" "r")
7065 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7066 (match_operand 3 "tie_symbolic_operand" "")]
7068 "TARGET_SUN_TLS && TARGET_ARCH64"
7069 "add\\t%1, %2, %0, %%tie_add(%a3)")
7071 (define_insn "tle_hix22_sp32"
7072 [(set (match_operand:SI 0 "register_operand" "=r")
7073 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7075 "TARGET_TLS && TARGET_ARCH32"
7076 "sethi\\t%%tle_hix22(%a1), %0")
7078 (define_insn "tle_lox10_sp32"
7079 [(set (match_operand:SI 0 "register_operand" "=r")
7080 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7081 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7083 "TARGET_TLS && TARGET_ARCH32"
7084 "xor\\t%1, %%tle_lox10(%a2), %0")
7086 (define_insn "tle_hix22_sp64"
7087 [(set (match_operand:DI 0 "register_operand" "=r")
7088 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7090 "TARGET_TLS && TARGET_ARCH64"
7091 "sethi\\t%%tle_hix22(%a1), %0")
7093 (define_insn "tle_lox10_sp64"
7094 [(set (match_operand:DI 0 "register_operand" "=r")
7095 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7096 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7098 "TARGET_TLS && TARGET_ARCH64"
7099 "xor\\t%1, %%tle_lox10(%a2), %0")
7101 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7102 (define_insn "*tldo_ldub_sp32"
7103 [(set (match_operand:QI 0 "register_operand" "=r")
7104 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7105 (match_operand 3 "tld_symbolic_operand" "")]
7107 (match_operand:SI 1 "register_operand" "r"))))]
7108 "TARGET_TLS && TARGET_ARCH32"
7109 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7110 [(set_attr "type" "load")
7111 (set_attr "us3load_type" "3cycle")])
7113 (define_insn "*tldo_ldub1_sp32"
7114 [(set (match_operand:HI 0 "register_operand" "=r")
7115 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7116 (match_operand 3 "tld_symbolic_operand" "")]
7118 (match_operand:SI 1 "register_operand" "r")))))]
7119 "TARGET_TLS && TARGET_ARCH32"
7120 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7121 [(set_attr "type" "load")
7122 (set_attr "us3load_type" "3cycle")])
7124 (define_insn "*tldo_ldub2_sp32"
7125 [(set (match_operand:SI 0 "register_operand" "=r")
7126 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7127 (match_operand 3 "tld_symbolic_operand" "")]
7129 (match_operand:SI 1 "register_operand" "r")))))]
7130 "TARGET_TLS && TARGET_ARCH32"
7131 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7132 [(set_attr "type" "load")
7133 (set_attr "us3load_type" "3cycle")])
7135 (define_insn "*tldo_ldsb1_sp32"
7136 [(set (match_operand:HI 0 "register_operand" "=r")
7137 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7138 (match_operand 3 "tld_symbolic_operand" "")]
7140 (match_operand:SI 1 "register_operand" "r")))))]
7141 "TARGET_TLS && TARGET_ARCH32"
7142 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7143 [(set_attr "type" "sload")
7144 (set_attr "us3load_type" "3cycle")])
7146 (define_insn "*tldo_ldsb2_sp32"
7147 [(set (match_operand:SI 0 "register_operand" "=r")
7148 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7149 (match_operand 3 "tld_symbolic_operand" "")]
7151 (match_operand:SI 1 "register_operand" "r")))))]
7152 "TARGET_TLS && TARGET_ARCH32"
7153 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7154 [(set_attr "type" "sload")
7155 (set_attr "us3load_type" "3cycle")])
7157 (define_insn "*tldo_ldub_sp64"
7158 [(set (match_operand:QI 0 "register_operand" "=r")
7159 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7160 (match_operand 3 "tld_symbolic_operand" "")]
7162 (match_operand:DI 1 "register_operand" "r"))))]
7163 "TARGET_TLS && TARGET_ARCH64"
7164 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7165 [(set_attr "type" "load")
7166 (set_attr "us3load_type" "3cycle")])
7168 (define_insn "*tldo_ldub1_sp64"
7169 [(set (match_operand:HI 0 "register_operand" "=r")
7170 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7171 (match_operand 3 "tld_symbolic_operand" "")]
7173 (match_operand:DI 1 "register_operand" "r")))))]
7174 "TARGET_TLS && TARGET_ARCH64"
7175 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7176 [(set_attr "type" "load")
7177 (set_attr "us3load_type" "3cycle")])
7179 (define_insn "*tldo_ldub2_sp64"
7180 [(set (match_operand:SI 0 "register_operand" "=r")
7181 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7182 (match_operand 3 "tld_symbolic_operand" "")]
7184 (match_operand:DI 1 "register_operand" "r")))))]
7185 "TARGET_TLS && TARGET_ARCH64"
7186 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7187 [(set_attr "type" "load")
7188 (set_attr "us3load_type" "3cycle")])
7190 (define_insn "*tldo_ldub3_sp64"
7191 [(set (match_operand:DI 0 "register_operand" "=r")
7192 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7193 (match_operand 3 "tld_symbolic_operand" "")]
7195 (match_operand:DI 1 "register_operand" "r")))))]
7196 "TARGET_TLS && TARGET_ARCH64"
7197 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7198 [(set_attr "type" "load")
7199 (set_attr "us3load_type" "3cycle")])
7201 (define_insn "*tldo_ldsb1_sp64"
7202 [(set (match_operand:HI 0 "register_operand" "=r")
7203 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7204 (match_operand 3 "tld_symbolic_operand" "")]
7206 (match_operand:DI 1 "register_operand" "r")))))]
7207 "TARGET_TLS && TARGET_ARCH64"
7208 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7209 [(set_attr "type" "sload")
7210 (set_attr "us3load_type" "3cycle")])
7212 (define_insn "*tldo_ldsb2_sp64"
7213 [(set (match_operand:SI 0 "register_operand" "=r")
7214 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7215 (match_operand 3 "tld_symbolic_operand" "")]
7217 (match_operand:DI 1 "register_operand" "r")))))]
7218 "TARGET_TLS && TARGET_ARCH64"
7219 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7220 [(set_attr "type" "sload")
7221 (set_attr "us3load_type" "3cycle")])
7223 (define_insn "*tldo_ldsb3_sp64"
7224 [(set (match_operand:DI 0 "register_operand" "=r")
7225 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7226 (match_operand 3 "tld_symbolic_operand" "")]
7228 (match_operand:DI 1 "register_operand" "r")))))]
7229 "TARGET_TLS && TARGET_ARCH64"
7230 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7231 [(set_attr "type" "sload")
7232 (set_attr "us3load_type" "3cycle")])
7234 (define_insn "*tldo_lduh_sp32"
7235 [(set (match_operand:HI 0 "register_operand" "=r")
7236 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7237 (match_operand 3 "tld_symbolic_operand" "")]
7239 (match_operand:SI 1 "register_operand" "r"))))]
7240 "TARGET_TLS && TARGET_ARCH32"
7241 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7242 [(set_attr "type" "load")
7243 (set_attr "us3load_type" "3cycle")])
7245 (define_insn "*tldo_lduh1_sp32"
7246 [(set (match_operand:SI 0 "register_operand" "=r")
7247 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7248 (match_operand 3 "tld_symbolic_operand" "")]
7250 (match_operand:SI 1 "register_operand" "r")))))]
7251 "TARGET_TLS && TARGET_ARCH32"
7252 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7253 [(set_attr "type" "load")
7254 (set_attr "us3load_type" "3cycle")])
7256 (define_insn "*tldo_ldsh1_sp32"
7257 [(set (match_operand:SI 0 "register_operand" "=r")
7258 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7259 (match_operand 3 "tld_symbolic_operand" "")]
7261 (match_operand:SI 1 "register_operand" "r")))))]
7262 "TARGET_TLS && TARGET_ARCH32"
7263 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7264 [(set_attr "type" "sload")
7265 (set_attr "us3load_type" "3cycle")])
7267 (define_insn "*tldo_lduh_sp64"
7268 [(set (match_operand:HI 0 "register_operand" "=r")
7269 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7270 (match_operand 3 "tld_symbolic_operand" "")]
7272 (match_operand:DI 1 "register_operand" "r"))))]
7273 "TARGET_TLS && TARGET_ARCH64"
7274 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7275 [(set_attr "type" "load")
7276 (set_attr "us3load_type" "3cycle")])
7278 (define_insn "*tldo_lduh1_sp64"
7279 [(set (match_operand:SI 0 "register_operand" "=r")
7280 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7281 (match_operand 3 "tld_symbolic_operand" "")]
7283 (match_operand:DI 1 "register_operand" "r")))))]
7284 "TARGET_TLS && TARGET_ARCH64"
7285 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7286 [(set_attr "type" "load")
7287 (set_attr "us3load_type" "3cycle")])
7289 (define_insn "*tldo_lduh2_sp64"
7290 [(set (match_operand:DI 0 "register_operand" "=r")
7291 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7292 (match_operand 3 "tld_symbolic_operand" "")]
7294 (match_operand:DI 1 "register_operand" "r")))))]
7295 "TARGET_TLS && TARGET_ARCH64"
7296 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7297 [(set_attr "type" "load")
7298 (set_attr "us3load_type" "3cycle")])
7300 (define_insn "*tldo_ldsh1_sp64"
7301 [(set (match_operand:SI 0 "register_operand" "=r")
7302 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7303 (match_operand 3 "tld_symbolic_operand" "")]
7305 (match_operand:DI 1 "register_operand" "r")))))]
7306 "TARGET_TLS && TARGET_ARCH64"
7307 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7308 [(set_attr "type" "sload")
7309 (set_attr "us3load_type" "3cycle")])
7311 (define_insn "*tldo_ldsh2_sp64"
7312 [(set (match_operand:DI 0 "register_operand" "=r")
7313 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7314 (match_operand 3 "tld_symbolic_operand" "")]
7316 (match_operand:DI 1 "register_operand" "r")))))]
7317 "TARGET_TLS && TARGET_ARCH64"
7318 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7319 [(set_attr "type" "sload")
7320 (set_attr "us3load_type" "3cycle")])
7322 (define_insn "*tldo_lduw_sp32"
7323 [(set (match_operand:SI 0 "register_operand" "=r")
7324 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7325 (match_operand 3 "tld_symbolic_operand" "")]
7327 (match_operand:SI 1 "register_operand" "r"))))]
7328 "TARGET_TLS && TARGET_ARCH32"
7329 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7330 [(set_attr "type" "load")])
7332 (define_insn "*tldo_lduw_sp64"
7333 [(set (match_operand:SI 0 "register_operand" "=r")
7334 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7335 (match_operand 3 "tld_symbolic_operand" "")]
7337 (match_operand:DI 1 "register_operand" "r"))))]
7338 "TARGET_TLS && TARGET_ARCH64"
7339 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7340 [(set_attr "type" "load")])
7342 (define_insn "*tldo_lduw1_sp64"
7343 [(set (match_operand:DI 0 "register_operand" "=r")
7344 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7345 (match_operand 3 "tld_symbolic_operand" "")]
7347 (match_operand:DI 1 "register_operand" "r")))))]
7348 "TARGET_TLS && TARGET_ARCH64"
7349 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7350 [(set_attr "type" "load")])
7352 (define_insn "*tldo_ldsw1_sp64"
7353 [(set (match_operand:DI 0 "register_operand" "=r")
7354 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7355 (match_operand 3 "tld_symbolic_operand" "")]
7357 (match_operand:DI 1 "register_operand" "r")))))]
7358 "TARGET_TLS && TARGET_ARCH64"
7359 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7360 [(set_attr "type" "sload")
7361 (set_attr "us3load_type" "3cycle")])
7363 (define_insn "*tldo_ldx_sp64"
7364 [(set (match_operand:DI 0 "register_operand" "=r")
7365 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7366 (match_operand 3 "tld_symbolic_operand" "")]
7368 (match_operand:DI 1 "register_operand" "r"))))]
7369 "TARGET_TLS && TARGET_ARCH64"
7370 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7371 [(set_attr "type" "load")])
7373 (define_insn "*tldo_stb_sp32"
7374 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7375 (match_operand 3 "tld_symbolic_operand" "")]
7377 (match_operand:SI 1 "register_operand" "r")))
7378 (match_operand:QI 0 "register_operand" "=r"))]
7379 "TARGET_TLS && TARGET_ARCH32"
7380 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7381 [(set_attr "type" "store")])
7383 (define_insn "*tldo_stb_sp64"
7384 [(set (mem:QI (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 (match_operand:QI 0 "register_operand" "=r"))]
7389 "TARGET_TLS && TARGET_ARCH64"
7390 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7391 [(set_attr "type" "store")])
7393 (define_insn "*tldo_sth_sp32"
7394 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7395 (match_operand 3 "tld_symbolic_operand" "")]
7397 (match_operand:SI 1 "register_operand" "r")))
7398 (match_operand:HI 0 "register_operand" "=r"))]
7399 "TARGET_TLS && TARGET_ARCH32"
7400 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7401 [(set_attr "type" "store")])
7403 (define_insn "*tldo_sth_sp64"
7404 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7405 (match_operand 3 "tld_symbolic_operand" "")]
7407 (match_operand:DI 1 "register_operand" "r")))
7408 (match_operand:HI 0 "register_operand" "=r"))]
7409 "TARGET_TLS && TARGET_ARCH64"
7410 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7411 [(set_attr "type" "store")])
7413 (define_insn "*tldo_stw_sp32"
7414 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7415 (match_operand 3 "tld_symbolic_operand" "")]
7417 (match_operand:SI 1 "register_operand" "r")))
7418 (match_operand:SI 0 "register_operand" "=r"))]
7419 "TARGET_TLS && TARGET_ARCH32"
7420 "st\t%0, [%1 + %2], %%tldo_add(%3)"
7421 [(set_attr "type" "store")])
7423 (define_insn "*tldo_stw_sp64"
7424 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7425 (match_operand 3 "tld_symbolic_operand" "")]
7427 (match_operand:DI 1 "register_operand" "r")))
7428 (match_operand:SI 0 "register_operand" "=r"))]
7429 "TARGET_TLS && TARGET_ARCH64"
7430 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7431 [(set_attr "type" "store")])
7433 (define_insn "*tldo_stx_sp64"
7434 [(set (mem:DI (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:DI 0 "register_operand" "=r"))]
7439 "TARGET_TLS && TARGET_ARCH64"
7440 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7441 [(set_attr "type" "store")])
7444 ;; Stack protector instructions.
7446 (define_expand "stack_protect_set"
7447 [(match_operand 0 "memory_operand" "")
7448 (match_operand 1 "memory_operand" "")]
7451 #ifdef TARGET_THREAD_SSP_OFFSET
7452 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7453 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7454 operands[1] = gen_rtx_MEM (Pmode, addr);
7457 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7459 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7463 (define_insn "stack_protect_setsi"
7464 [(set (match_operand:SI 0 "memory_operand" "=m")
7465 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7466 (set (match_scratch:SI 2 "=&r") (const_int 0))]
7468 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
7469 [(set_attr "type" "multi")
7470 (set_attr "length" "3")])
7472 (define_insn "stack_protect_setdi"
7473 [(set (match_operand:DI 0 "memory_operand" "=m")
7474 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7475 (set (match_scratch:DI 2 "=&r") (const_int 0))]
7477 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
7478 [(set_attr "type" "multi")
7479 (set_attr "length" "3")])
7481 (define_expand "stack_protect_test"
7482 [(match_operand 0 "memory_operand" "")
7483 (match_operand 1 "memory_operand" "")
7484 (match_operand 2 "" "")]
7488 #ifdef TARGET_THREAD_SSP_OFFSET
7489 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7490 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7491 operands[1] = gen_rtx_MEM (Pmode, addr);
7495 result = gen_reg_rtx (Pmode);
7496 emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
7497 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7498 emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
7502 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7503 result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
7504 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7505 emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
7510 (define_insn "stack_protect_testsi"
7512 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
7513 (match_operand:SI 1 "memory_operand" "m")]
7515 (set (match_scratch:SI 3 "=r") (const_int 0))
7516 (clobber (match_scratch:SI 2 "=&r"))]
7518 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
7519 [(set_attr "type" "multi")
7520 (set_attr "length" "4")])
7522 (define_insn "stack_protect_testdi"
7523 [(set (match_operand:DI 0 "register_operand" "=&r")
7524 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7525 (match_operand:DI 2 "memory_operand" "m")]
7527 (set (match_scratch:DI 3 "=r") (const_int 0))]
7529 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
7530 [(set_attr "type" "multi")
7531 (set_attr "length" "4")])
7534 ;; Vector instructions.
7536 (define_insn "addv2si3"
7537 [(set (match_operand:V2SI 0 "register_operand" "=e")
7538 (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7539 (match_operand:V2SI 2 "register_operand" "e")))]
7541 "fpadd32\t%1, %2, %0"
7542 [(set_attr "type" "fga")
7543 (set_attr "fptype" "double")])
7545 (define_insn "addv4hi3"
7546 [(set (match_operand:V4HI 0 "register_operand" "=e")
7547 (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7548 (match_operand:V4HI 2 "register_operand" "e")))]
7550 "fpadd16\t%1, %2, %0"
7551 [(set_attr "type" "fga")
7552 (set_attr "fptype" "double")])
7554 ;; fpadd32s is emitted by the addsi3 pattern.
7556 (define_insn "addv2hi3"
7557 [(set (match_operand:V2HI 0 "register_operand" "=f")
7558 (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7559 (match_operand:V2HI 2 "register_operand" "f")))]
7561 "fpadd16s\t%1, %2, %0"
7562 [(set_attr "type" "fga")
7563 (set_attr "fptype" "single")])
7565 (define_insn "subv2si3"
7566 [(set (match_operand:V2SI 0 "register_operand" "=e")
7567 (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7568 (match_operand:V2SI 2 "register_operand" "e")))]
7570 "fpsub32\t%1, %2, %0"
7571 [(set_attr "type" "fga")
7572 (set_attr "fptype" "double")])
7574 (define_insn "subv4hi3"
7575 [(set (match_operand:V4HI 0 "register_operand" "=e")
7576 (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7577 (match_operand:V4HI 2 "register_operand" "e")))]
7579 "fpsub16\t%1, %2, %0"
7580 [(set_attr "type" "fga")
7581 (set_attr "fptype" "double")])
7583 ;; fpsub32s is emitted by the subsi3 pattern.
7585 (define_insn "subv2hi3"
7586 [(set (match_operand:V2HI 0 "register_operand" "=f")
7587 (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7588 (match_operand:V2HI 2 "register_operand" "f")))]
7590 "fpsub16s\t%1, %2, %0"
7591 [(set_attr "type" "fga")
7592 (set_attr "fptype" "single")])
7594 ;; All other logical instructions have integer equivalents so they
7595 ;; are defined together.
7597 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
7599 (define_insn "*nand<V64:mode>_vis"
7600 [(set (match_operand:V64 0 "register_operand" "=e")
7601 (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
7602 (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
7605 [(set_attr "type" "fga")
7606 (set_attr "fptype" "double")])
7608 (define_insn "*nand<V32:mode>_vis"
7609 [(set (match_operand:V32 0 "register_operand" "=f")
7610 (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
7611 (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
7613 "fnands\t%1, %2, %0"
7614 [(set_attr "type" "fga")
7615 (set_attr "fptype" "single")])
7617 ;; Hard to generate VIS instructions. We have builtins for these.
7619 (define_insn "fpack16_vis"
7620 [(set (match_operand:V4QI 0 "register_operand" "=f")
7621 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
7625 [(set_attr "type" "fga")
7626 (set_attr "fptype" "double")])
7628 (define_insn "fpackfix_vis"
7629 [(set (match_operand:V2HI 0 "register_operand" "=f")
7630 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
7634 [(set_attr "type" "fga")
7635 (set_attr "fptype" "double")])
7637 (define_insn "fpack32_vis"
7638 [(set (match_operand:V8QI 0 "register_operand" "=e")
7639 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
7640 (match_operand:V8QI 2 "register_operand" "e")]
7643 "fpack32\t%1, %2, %0"
7644 [(set_attr "type" "fga")
7645 (set_attr "fptype" "double")])
7647 (define_insn "fexpand_vis"
7648 [(set (match_operand:V4HI 0 "register_operand" "=e")
7649 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
7653 [(set_attr "type" "fga")
7654 (set_attr "fptype" "double")])
7656 ;; It may be possible to describe this operation as (1 indexed):
7657 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
7658 ;; 1,5,10,14,19,23,28,32)
7659 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
7660 ;; because vec_merge expects all the operands to be of the same type.
7661 (define_insn "fpmerge_vis"
7662 [(set (match_operand:V8QI 0 "register_operand" "=e")
7663 (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
7664 (match_operand:V4QI 2 "register_operand" "f")]
7667 "fpmerge\t%1, %2, %0"
7668 [(set_attr "type" "fga")
7669 (set_attr "fptype" "double")])
7671 ;; Partitioned multiply instructions
7672 (define_insn "fmul8x16_vis"
7673 [(set (match_operand:V4HI 0 "register_operand" "=e")
7674 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7675 (match_operand:V4HI 2 "register_operand" "e")))]
7677 "fmul8x16\t%1, %2, %0"
7678 [(set_attr "type" "fpmul")
7679 (set_attr "fptype" "double")])
7681 ;; Only one of the following two insns can be a multiply.
7682 (define_insn "fmul8x16au_vis"
7683 [(set (match_operand:V4HI 0 "register_operand" "=e")
7684 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7685 (match_operand:V2HI 2 "register_operand" "f")))]
7687 "fmul8x16au\t%1, %2, %0"
7688 [(set_attr "type" "fpmul")
7689 (set_attr "fptype" "double")])
7691 (define_insn "fmul8x16al_vis"
7692 [(set (match_operand:V4HI 0 "register_operand" "=e")
7693 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
7694 (match_operand:V2HI 2 "register_operand" "f")]
7697 "fmul8x16al\t%1, %2, %0"
7698 [(set_attr "type" "fpmul")
7699 (set_attr "fptype" "double")])
7701 ;; Only one of the following two insns can be a multiply.
7702 (define_insn "fmul8sux16_vis"
7703 [(set (match_operand:V4HI 0 "register_operand" "=e")
7704 (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
7705 (match_operand:V4HI 2 "register_operand" "e")))]
7707 "fmul8sux16\t%1, %2, %0"
7708 [(set_attr "type" "fpmul")
7709 (set_attr "fptype" "double")])
7711 (define_insn "fmul8ulx16_vis"
7712 [(set (match_operand:V4HI 0 "register_operand" "=e")
7713 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
7714 (match_operand:V4HI 2 "register_operand" "e")]
7717 "fmul8ulx16\t%1, %2, %0"
7718 [(set_attr "type" "fpmul")
7719 (set_attr "fptype" "double")])
7721 ;; Only one of the following two insns can be a multiply.
7722 (define_insn "fmuld8sux16_vis"
7723 [(set (match_operand:V2SI 0 "register_operand" "=e")
7724 (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
7725 (match_operand:V2HI 2 "register_operand" "f")))]
7727 "fmuld8sux16\t%1, %2, %0"
7728 [(set_attr "type" "fpmul")
7729 (set_attr "fptype" "double")])
7731 (define_insn "fmuld8ulx16_vis"
7732 [(set (match_operand:V2SI 0 "register_operand" "=e")
7733 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
7734 (match_operand:V2HI 2 "register_operand" "f")]
7737 "fmuld8ulx16\t%1, %2, %0"
7738 [(set_attr "type" "fpmul")
7739 (set_attr "fptype" "double")])
7741 ;; Using faligndata only makes sense after an alignaddr since the choice of
7742 ;; bytes to take out of each operand is dependent on the results of the last
7744 (define_insn "faligndata<V64I:mode>_vis"
7745 [(set (match_operand:V64I 0 "register_operand" "=e")
7746 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
7747 (match_operand:V64I 2 "register_operand" "e")]
7750 "faligndata\t%1, %2, %0"
7751 [(set_attr "type" "fga")
7752 (set_attr "fptype" "double")])
7754 (define_insn "alignaddr<P:mode>_vis"
7755 [(set (match_operand:P 0 "register_operand" "=r")
7756 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
7757 (match_operand:P 2 "register_or_zero_operand" "rJ")]
7760 "alignaddr\t%r1, %r2, %0")
7762 (define_insn "pdist_vis"
7763 [(set (match_operand:DI 0 "register_operand" "=e")
7764 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
7765 (match_operand:V8QI 2 "register_operand" "e")
7766 (match_operand:DI 3 "register_operand" "0")]
7770 [(set_attr "type" "fga")
7771 (set_attr "fptype" "double")])