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.
121 (const (symbol_ref "sparc_cpu_attr")))
123 ;; Attribute for the instruction set.
124 ;; At present we only need to distinguish v9/!v9, but for clarity we
125 ;; test TARGET_V8 too.
126 (define_attr "isa" "v7,v8,v9,sparclet"
128 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
129 (symbol_ref "TARGET_V8") (const_string "v8")
130 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
131 (const_string "v7"))))
137 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
145 fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,
148 multi,savew,flushw,iflush,trap"
149 (const_string "ialu"))
151 ;; True if branch/call has empty delay slot and will emit a nop in it
152 (define_attr "empty_delay_slot" "false,true"
153 (symbol_ref "(empty_delay_slot (insn)
154 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
156 (define_attr "branch_type" "none,icc,fcc,reg"
157 (const_string "none"))
159 (define_attr "pic" "false,true"
160 (symbol_ref "(flag_pic != 0 ? PIC_TRUE : PIC_FALSE)"))
162 (define_attr "calls_alloca" "false,true"
163 (symbol_ref "(cfun->calls_alloca != 0
164 ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)"))
166 (define_attr "calls_eh_return" "false,true"
167 (symbol_ref "(crtl->calls_eh_return != 0
168 ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)"))
170 (define_attr "leaf_function" "false,true"
171 (symbol_ref "(current_function_uses_only_leaf_regs != 0
172 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
174 (define_attr "delayed_branch" "false,true"
175 (symbol_ref "(flag_delayed_branch != 0
176 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
178 (define_attr "flat" "false,true"
179 (symbol_ref "(TARGET_FLAT != 0
180 ? FLAT_TRUE : FLAT_FALSE)"))
182 ;; Length (in # of insns).
183 ;; Beware that setting a length greater or equal to 3 for conditional branches
184 ;; has a side-effect (see output_cbranch and output_v9branch).
185 (define_attr "length" ""
186 (cond [(eq_attr "type" "uncond_branch,call")
187 (if_then_else (eq_attr "empty_delay_slot" "true")
190 (eq_attr "type" "sibcall")
191 (if_then_else (eq_attr "leaf_function" "true")
192 (if_then_else (eq_attr "empty_delay_slot" "true")
195 (if_then_else (eq_attr "empty_delay_slot" "true")
198 (eq_attr "branch_type" "icc")
199 (if_then_else (match_operand 0 "noov_compare64_operator" "")
200 (if_then_else (lt (pc) (match_dup 1))
201 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
202 (if_then_else (eq_attr "empty_delay_slot" "true")
205 (if_then_else (eq_attr "empty_delay_slot" "true")
208 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
209 (if_then_else (eq_attr "empty_delay_slot" "true")
212 (if_then_else (eq_attr "empty_delay_slot" "true")
215 (if_then_else (eq_attr "empty_delay_slot" "true")
218 (eq_attr "branch_type" "fcc")
219 (if_then_else (match_operand 0 "fcc0_register_operand" "")
220 (if_then_else (eq_attr "empty_delay_slot" "true")
221 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
224 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
227 (if_then_else (lt (pc) (match_dup 2))
228 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
229 (if_then_else (eq_attr "empty_delay_slot" "true")
232 (if_then_else (eq_attr "empty_delay_slot" "true")
235 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
236 (if_then_else (eq_attr "empty_delay_slot" "true")
239 (if_then_else (eq_attr "empty_delay_slot" "true")
242 (eq_attr "branch_type" "reg")
243 (if_then_else (lt (pc) (match_dup 2))
244 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
245 (if_then_else (eq_attr "empty_delay_slot" "true")
248 (if_then_else (eq_attr "empty_delay_slot" "true")
251 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
252 (if_then_else (eq_attr "empty_delay_slot" "true")
255 (if_then_else (eq_attr "empty_delay_slot" "true")
261 (define_attr "fptype" "single,double"
262 (const_string "single"))
264 ;; UltraSPARC-III integer load type.
265 (define_attr "us3load_type" "2cycle,3cycle"
266 (const_string "2cycle"))
268 (define_asm_attributes
269 [(set_attr "length" "2")
270 (set_attr "type" "multi")])
272 ;; Attributes for instruction and branch scheduling
273 (define_attr "tls_call_delay" "false,true"
274 (symbol_ref "(tls_call_delay (insn)
275 ? TLS_CALL_DELAY_TRUE : TLS_CALL_DELAY_FALSE)"))
277 (define_attr "in_call_delay" "false,true"
278 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
279 (const_string "false")
280 (eq_attr "type" "load,fpload,store,fpstore")
281 (if_then_else (eq_attr "length" "1")
282 (const_string "true")
283 (const_string "false"))]
284 (if_then_else (and (eq_attr "length" "1")
285 (eq_attr "tls_call_delay" "true"))
286 (const_string "true")
287 (const_string "false"))))
289 (define_attr "eligible_for_sibcall_delay" "false,true"
290 (symbol_ref "(eligible_for_sibcall_delay (insn)
291 ? ELIGIBLE_FOR_SIBCALL_DELAY_TRUE
292 : ELIGIBLE_FOR_SIBCALL_DELAY_FALSE)"))
294 (define_attr "eligible_for_return_delay" "false,true"
295 (symbol_ref "(eligible_for_return_delay (insn)
296 ? ELIGIBLE_FOR_RETURN_DELAY_TRUE
297 : ELIGIBLE_FOR_RETURN_DELAY_FALSE)"))
299 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
300 ;; branches. This would allow us to remove the nop always inserted before
301 ;; a floating point branch.
303 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
304 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
305 ;; This is because doing so will add several pipeline stalls to the path
306 ;; that the load/store did not come from. Unfortunately, there is no way
307 ;; to prevent fill_eager_delay_slots from using load/store without completely
308 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
309 ;; because it prevents us from moving back the final store of inner loops.
311 (define_attr "in_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_uncond_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_attr "in_annul_branch_delay" "false,true"
324 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
325 (eq_attr "length" "1"))
326 (const_string "true")
327 (const_string "false")))
329 (define_delay (eq_attr "type" "call")
330 [(eq_attr "in_call_delay" "true") (nil) (nil)])
332 (define_delay (eq_attr "type" "sibcall")
333 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
335 (define_delay (eq_attr "type" "branch")
336 [(eq_attr "in_branch_delay" "true")
337 (nil) (eq_attr "in_annul_branch_delay" "true")])
339 (define_delay (eq_attr "type" "uncond_branch")
340 [(eq_attr "in_uncond_branch_delay" "true")
343 (define_delay (eq_attr "type" "return")
344 [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
347 ;; Include SPARC DFA schedulers
349 (include "cypress.md")
350 (include "supersparc.md")
351 (include "hypersparc.md")
353 (include "sparclet.md")
354 (include "ultra1_2.md")
355 (include "ultra3.md")
356 (include "niagara.md")
357 (include "niagara2.md")
360 ;; Operand and operator predicates and constraints
362 (include "predicates.md")
363 (include "constraints.md")
366 ;; Compare instructions.
368 ;; These are just the DEFINE_INSNs to match the patterns and the
369 ;; DEFINE_SPLITs for some of the scc insns that actually require
370 ;; more than one machine instruction. DEFINE_EXPANDs are further down.
372 ;; The compare DEFINE_INSNs.
374 (define_insn "*cmpsi_insn"
376 (compare:CC (match_operand:SI 0 "register_operand" "r")
377 (match_operand:SI 1 "arith_operand" "rI")))]
380 [(set_attr "type" "compare")])
382 (define_insn "*cmpdi_sp64"
384 (compare:CCX (match_operand:DI 0 "register_operand" "r")
385 (match_operand:DI 1 "arith_operand" "rI")))]
388 [(set_attr "type" "compare")])
390 (define_insn "*cmpsf_fpe"
391 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
392 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
393 (match_operand:SF 2 "register_operand" "f")))]
397 return "fcmpes\t%0, %1, %2";
398 return "fcmpes\t%1, %2";
400 [(set_attr "type" "fpcmp")])
402 (define_insn "*cmpdf_fpe"
403 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
404 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
405 (match_operand:DF 2 "register_operand" "e")))]
409 return "fcmped\t%0, %1, %2";
410 return "fcmped\t%1, %2";
412 [(set_attr "type" "fpcmp")
413 (set_attr "fptype" "double")])
415 (define_insn "*cmptf_fpe"
416 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
417 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
418 (match_operand:TF 2 "register_operand" "e")))]
419 "TARGET_FPU && TARGET_HARD_QUAD"
422 return "fcmpeq\t%0, %1, %2";
423 return "fcmpeq\t%1, %2";
425 [(set_attr "type" "fpcmp")])
427 (define_insn "*cmpsf_fp"
428 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
429 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
430 (match_operand:SF 2 "register_operand" "f")))]
434 return "fcmps\t%0, %1, %2";
435 return "fcmps\t%1, %2";
437 [(set_attr "type" "fpcmp")])
439 (define_insn "*cmpdf_fp"
440 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
441 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
442 (match_operand:DF 2 "register_operand" "e")))]
446 return "fcmpd\t%0, %1, %2";
447 return "fcmpd\t%1, %2";
449 [(set_attr "type" "fpcmp")
450 (set_attr "fptype" "double")])
452 (define_insn "*cmptf_fp"
453 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
454 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
455 (match_operand:TF 2 "register_operand" "e")))]
456 "TARGET_FPU && TARGET_HARD_QUAD"
459 return "fcmpq\t%0, %1, %2";
460 return "fcmpq\t%1, %2";
462 [(set_attr "type" "fpcmp")])
464 ;; Next come the scc insns.
466 (define_expand "cstoresi4"
467 [(use (match_operator 1 "comparison_operator"
468 [(match_operand:SI 2 "compare_operand" "")
469 (match_operand:SI 3 "arith_operand" "")]))
470 (clobber (match_operand:SI 0 "register_operand"))]
473 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
474 operands[2] = force_reg (SImode, operands[2]);
475 if (emit_scc_insn (operands)) DONE; else FAIL;
478 (define_expand "cstoredi4"
479 [(use (match_operator 1 "comparison_operator"
480 [(match_operand:DI 2 "compare_operand" "")
481 (match_operand:DI 3 "arith_operand" "")]))
482 (clobber (match_operand:SI 0 "register_operand"))]
485 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
486 operands[2] = force_reg (DImode, operands[2]);
487 if (emit_scc_insn (operands)) DONE; else FAIL;
490 (define_expand "cstore<F:mode>4"
491 [(use (match_operator 1 "comparison_operator"
492 [(match_operand:F 2 "register_operand" "")
493 (match_operand:F 3 "register_operand" "")]))
494 (clobber (match_operand:SI 0 "register_operand"))]
496 { if (emit_scc_insn (operands)) DONE; else FAIL; })
500 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
501 ;; generate addcc/subcc instructions.
503 (define_expand "seqsi_special"
505 (xor:SI (match_operand:SI 1 "register_operand" "")
506 (match_operand:SI 2 "register_operand" "")))
507 (parallel [(set (match_operand:SI 0 "register_operand" "")
508 (eq:SI (match_dup 3) (const_int 0)))
509 (clobber (reg:CC 100))])]
511 { operands[3] = gen_reg_rtx (SImode); })
513 (define_expand "seqdi_special"
515 (xor:DI (match_operand:DI 1 "register_operand" "")
516 (match_operand:DI 2 "register_operand" "")))
517 (set (match_operand:SI 0 "register_operand" "")
518 (eq:SI (match_dup 3) (const_int 0)))]
520 { operands[3] = gen_reg_rtx (DImode); })
522 (define_expand "snesi_special"
524 (xor:SI (match_operand:SI 1 "register_operand" "")
525 (match_operand:SI 2 "register_operand" "")))
526 (parallel [(set (match_operand:SI 0 "register_operand" "")
527 (ne:SI (match_dup 3) (const_int 0)))
528 (clobber (reg:CC 100))])]
530 { operands[3] = gen_reg_rtx (SImode); })
532 (define_expand "snedi_special"
534 (xor:DI (match_operand:DI 1 "register_operand" "")
535 (match_operand:DI 2 "register_operand" "")))
536 (set (match_operand:SI 0 "register_operand" "")
537 (ne:SI (match_dup 3) (const_int 0)))]
539 { operands[3] = gen_reg_rtx (DImode); })
542 ;; Now the DEFINE_INSNs for the scc cases.
544 ;; The SEQ and SNE patterns are special because they can be done
545 ;; without any branching and do not involve a COMPARE. We want
546 ;; them to always use the splits below so the results can be
549 (define_insn_and_split "*snesi_zero"
550 [(set (match_operand:SI 0 "register_operand" "=r")
551 (ne:SI (match_operand:SI 1 "register_operand" "r")
553 (clobber (reg:CC 100))]
557 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
559 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
561 [(set_attr "length" "2")])
563 (define_insn_and_split "*neg_snesi_zero"
564 [(set (match_operand:SI 0 "register_operand" "=r")
565 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
567 (clobber (reg:CC 100))]
571 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
573 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
575 [(set_attr "length" "2")])
577 (define_insn_and_split "*snesi_zero_extend"
578 [(set (match_operand:DI 0 "register_operand" "=r")
579 (ne:DI (match_operand:SI 1 "register_operand" "r")
581 (clobber (reg:CC 100))]
585 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
588 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
590 (ltu:SI (reg:CC_NOOV 100)
593 [(set_attr "length" "2")])
595 (define_insn_and_split "*snedi_zero"
596 [(set (match_operand:DI 0 "register_operand" "=&r")
597 (ne:DI (match_operand:DI 1 "register_operand" "r")
601 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
602 [(set (match_dup 0) (const_int 0))
603 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
608 [(set_attr "length" "2")])
610 (define_insn_and_split "*neg_snedi_zero"
611 [(set (match_operand:DI 0 "register_operand" "=&r")
612 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
616 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
617 [(set (match_dup 0) (const_int 0))
618 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
623 [(set_attr "length" "2")])
625 (define_insn_and_split "*snedi_zero_trunc"
626 [(set (match_operand:SI 0 "register_operand" "=&r")
627 (ne:SI (match_operand:DI 1 "register_operand" "r")
631 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
632 [(set (match_dup 0) (const_int 0))
633 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
638 [(set_attr "length" "2")])
640 (define_insn_and_split "*seqsi_zero"
641 [(set (match_operand:SI 0 "register_operand" "=r")
642 (eq:SI (match_operand:SI 1 "register_operand" "r")
644 (clobber (reg:CC 100))]
648 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
650 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
652 [(set_attr "length" "2")])
654 (define_insn_and_split "*neg_seqsi_zero"
655 [(set (match_operand:SI 0 "register_operand" "=r")
656 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
658 (clobber (reg:CC 100))]
662 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
664 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
666 [(set_attr "length" "2")])
668 (define_insn_and_split "*seqsi_zero_extend"
669 [(set (match_operand:DI 0 "register_operand" "=r")
670 (eq:DI (match_operand:SI 1 "register_operand" "r")
672 (clobber (reg:CC 100))]
676 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
679 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
681 (ltu:SI (reg:CC_NOOV 100)
684 [(set_attr "length" "2")])
686 (define_insn_and_split "*seqdi_zero"
687 [(set (match_operand:DI 0 "register_operand" "=&r")
688 (eq:DI (match_operand:DI 1 "register_operand" "r")
692 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
693 [(set (match_dup 0) (const_int 0))
694 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
699 [(set_attr "length" "2")])
701 (define_insn_and_split "*neg_seqdi_zero"
702 [(set (match_operand:DI 0 "register_operand" "=&r")
703 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
707 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
708 [(set (match_dup 0) (const_int 0))
709 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
714 [(set_attr "length" "2")])
716 (define_insn_and_split "*seqdi_zero_trunc"
717 [(set (match_operand:SI 0 "register_operand" "=&r")
718 (eq:SI (match_operand:DI 1 "register_operand" "r")
722 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
723 [(set (match_dup 0) (const_int 0))
724 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
729 [(set_attr "length" "2")])
731 ;; We can also do (x + (i == 0)) and related, so put them in.
732 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
735 (define_insn_and_split "*x_plus_i_ne_0"
736 [(set (match_operand:SI 0 "register_operand" "=r")
737 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
739 (match_operand:SI 2 "register_operand" "r")))
740 (clobber (reg:CC 100))]
744 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
746 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
749 [(set_attr "length" "2")])
751 (define_insn_and_split "*x_minus_i_ne_0"
752 [(set (match_operand:SI 0 "register_operand" "=r")
753 (minus:SI (match_operand:SI 2 "register_operand" "r")
754 (ne:SI (match_operand:SI 1 "register_operand" "r")
756 (clobber (reg:CC 100))]
760 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
762 (set (match_dup 0) (minus:SI (match_dup 2)
763 (ltu:SI (reg:CC 100) (const_int 0))))]
765 [(set_attr "length" "2")])
767 (define_insn_and_split "*x_plus_i_eq_0"
768 [(set (match_operand:SI 0 "register_operand" "=r")
769 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
771 (match_operand:SI 2 "register_operand" "r")))
772 (clobber (reg:CC 100))]
776 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
778 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
781 [(set_attr "length" "2")])
783 (define_insn_and_split "*x_minus_i_eq_0"
784 [(set (match_operand:SI 0 "register_operand" "=r")
785 (minus:SI (match_operand:SI 2 "register_operand" "r")
786 (eq:SI (match_operand:SI 1 "register_operand" "r")
788 (clobber (reg:CC 100))]
792 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
794 (set (match_dup 0) (minus:SI (match_dup 2)
795 (geu:SI (reg:CC 100) (const_int 0))))]
797 [(set_attr "length" "2")])
799 ;; We can also do GEU and LTU directly, but these operate after a compare.
800 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
803 (define_insn "*sltu_insn"
804 [(set (match_operand:SI 0 "register_operand" "=r")
805 (ltu:SI (reg:CC 100) (const_int 0)))]
808 [(set_attr "type" "ialuX")])
810 (define_insn "*neg_sltu_insn"
811 [(set (match_operand:SI 0 "register_operand" "=r")
812 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
815 [(set_attr "type" "ialuX")])
817 ;; ??? Combine should canonicalize these next two to the same pattern.
818 (define_insn "*neg_sltu_minus_x"
819 [(set (match_operand:SI 0 "register_operand" "=r")
820 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
821 (match_operand:SI 1 "arith_operand" "rI")))]
824 [(set_attr "type" "ialuX")])
826 (define_insn "*neg_sltu_plus_x"
827 [(set (match_operand:SI 0 "register_operand" "=r")
828 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
829 (match_operand:SI 1 "arith_operand" "rI"))))]
832 [(set_attr "type" "ialuX")])
834 (define_insn "*sgeu_insn"
835 [(set (match_operand:SI 0 "register_operand" "=r")
836 (geu:SI (reg:CC 100) (const_int 0)))]
839 [(set_attr "type" "ialuX")])
841 (define_insn "*neg_sgeu_insn"
842 [(set (match_operand:SI 0 "register_operand" "=r")
843 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
846 [(set_attr "type" "ialuX")])
848 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
849 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
852 (define_insn "*sltu_plus_x"
853 [(set (match_operand:SI 0 "register_operand" "=r")
854 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
855 (match_operand:SI 1 "arith_operand" "rI")))]
858 [(set_attr "type" "ialuX")])
860 (define_insn "*sltu_plus_x_plus_y"
861 [(set (match_operand:SI 0 "register_operand" "=r")
862 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
863 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
864 (match_operand:SI 2 "arith_operand" "rI"))))]
867 [(set_attr "type" "ialuX")])
869 (define_insn "*x_minus_sltu"
870 [(set (match_operand:SI 0 "register_operand" "=r")
871 (minus:SI (match_operand:SI 1 "register_operand" "r")
872 (ltu:SI (reg:CC 100) (const_int 0))))]
875 [(set_attr "type" "ialuX")])
877 ;; ??? Combine should canonicalize these next two to the same pattern.
878 (define_insn "*x_minus_y_minus_sltu"
879 [(set (match_operand:SI 0 "register_operand" "=r")
880 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
881 (match_operand:SI 2 "arith_operand" "rI"))
882 (ltu:SI (reg:CC 100) (const_int 0))))]
885 [(set_attr "type" "ialuX")])
887 (define_insn "*x_minus_sltu_plus_y"
888 [(set (match_operand:SI 0 "register_operand" "=r")
889 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
890 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
891 (match_operand:SI 2 "arith_operand" "rI"))))]
894 [(set_attr "type" "ialuX")])
896 (define_insn "*sgeu_plus_x"
897 [(set (match_operand:SI 0 "register_operand" "=r")
898 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
899 (match_operand:SI 1 "register_operand" "r")))]
902 [(set_attr "type" "ialuX")])
904 (define_insn "*x_minus_sgeu"
905 [(set (match_operand:SI 0 "register_operand" "=r")
906 (minus:SI (match_operand:SI 1 "register_operand" "r")
907 (geu:SI (reg:CC 100) (const_int 0))))]
910 [(set_attr "type" "ialuX")])
913 [(set (match_operand:SI 0 "register_operand" "")
914 (match_operator:SI 2 "noov_compare_operator"
915 [(match_operand 1 "icc_or_fcc_register_operand" "")
918 && REGNO (operands[1]) == SPARC_ICC_REG
919 && (GET_MODE (operands[1]) == CCXmode
920 /* 32-bit LTU/GEU are better implemented using addx/subx. */
921 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
922 [(set (match_dup 0) (const_int 0))
924 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
930 ;; These control RTL generation for conditional jump insns
932 (define_expand "cbranchcc4"
934 (if_then_else (match_operator 0 "comparison_operator"
935 [(match_operand 1 "compare_operand" "")
936 (match_operand 2 "const_zero_operand" "")])
937 (label_ref (match_operand 3 "" ""))
942 (define_expand "cbranchsi4"
943 [(use (match_operator 0 "comparison_operator"
944 [(match_operand:SI 1 "compare_operand" "")
945 (match_operand:SI 2 "arith_operand" "")]))
946 (use (match_operand 3 ""))]
949 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
950 operands[1] = force_reg (SImode, operands[1]);
951 emit_conditional_branch_insn (operands);
955 (define_expand "cbranchdi4"
956 [(use (match_operator 0 "comparison_operator"
957 [(match_operand:DI 1 "compare_operand" "")
958 (match_operand:DI 2 "arith_operand" "")]))
959 (use (match_operand 3 ""))]
962 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
963 operands[1] = force_reg (DImode, operands[1]);
964 emit_conditional_branch_insn (operands);
968 (define_expand "cbranch<F:mode>4"
969 [(use (match_operator 0 "comparison_operator"
970 [(match_operand:F 1 "register_operand" "")
971 (match_operand:F 2 "register_operand" "")]))
972 (use (match_operand 3 ""))]
974 { emit_conditional_branch_insn (operands); DONE; })
977 ;; Now match both normal and inverted jump.
979 ;; XXX fpcmp nop braindamage
980 (define_insn "*normal_branch"
982 (if_then_else (match_operator 0 "noov_compare_operator"
983 [(reg 100) (const_int 0)])
984 (label_ref (match_operand 1 "" ""))
988 return output_cbranch (operands[0], operands[1], 1, 0,
989 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
992 [(set_attr "type" "branch")
993 (set_attr "branch_type" "icc")])
995 ;; XXX fpcmp nop braindamage
996 (define_insn "*inverted_branch"
998 (if_then_else (match_operator 0 "noov_compare_operator"
999 [(reg 100) (const_int 0)])
1001 (label_ref (match_operand 1 "" ""))))]
1004 return output_cbranch (operands[0], operands[1], 1, 1,
1005 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1008 [(set_attr "type" "branch")
1009 (set_attr "branch_type" "icc")])
1011 ;; XXX fpcmp nop braindamage
1012 (define_insn "*normal_fp_branch"
1014 (if_then_else (match_operator 1 "comparison_operator"
1015 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1017 (label_ref (match_operand 2 "" ""))
1021 return output_cbranch (operands[1], operands[2], 2, 0,
1022 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1025 [(set_attr "type" "branch")
1026 (set_attr "branch_type" "fcc")])
1028 ;; XXX fpcmp nop braindamage
1029 (define_insn "*inverted_fp_branch"
1031 (if_then_else (match_operator 1 "comparison_operator"
1032 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1035 (label_ref (match_operand 2 "" ""))))]
1038 return output_cbranch (operands[1], operands[2], 2, 1,
1039 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1042 [(set_attr "type" "branch")
1043 (set_attr "branch_type" "fcc")])
1045 ;; XXX fpcmp nop braindamage
1046 (define_insn "*normal_fpe_branch"
1048 (if_then_else (match_operator 1 "comparison_operator"
1049 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1051 (label_ref (match_operand 2 "" ""))
1055 return output_cbranch (operands[1], operands[2], 2, 0,
1056 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1059 [(set_attr "type" "branch")
1060 (set_attr "branch_type" "fcc")])
1062 ;; XXX fpcmp nop braindamage
1063 (define_insn "*inverted_fpe_branch"
1065 (if_then_else (match_operator 1 "comparison_operator"
1066 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1069 (label_ref (match_operand 2 "" ""))))]
1072 return output_cbranch (operands[1], operands[2], 2, 1,
1073 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1076 [(set_attr "type" "branch")
1077 (set_attr "branch_type" "fcc")])
1079 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1080 ;; in the architecture.
1082 ;; There are no 32 bit brreg insns.
1085 (define_insn "*normal_int_branch_sp64"
1087 (if_then_else (match_operator 0 "v9_register_compare_operator"
1088 [(match_operand:DI 1 "register_operand" "r")
1090 (label_ref (match_operand 2 "" ""))
1094 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1095 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1098 [(set_attr "type" "branch")
1099 (set_attr "branch_type" "reg")])
1102 (define_insn "*inverted_int_branch_sp64"
1104 (if_then_else (match_operator 0 "v9_register_compare_operator"
1105 [(match_operand:DI 1 "register_operand" "r")
1108 (label_ref (match_operand 2 "" ""))))]
1111 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1112 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1115 [(set_attr "type" "branch")
1116 (set_attr "branch_type" "reg")])
1119 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1120 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1121 ;; that adds the PC value at the call point to register #(operand 3).
1123 (define_insn "load_pcrel_sym<P:mode>"
1124 [(set (match_operand:P 0 "register_operand" "=r")
1125 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1126 (match_operand:P 2 "call_address_operand" "")
1127 (match_operand:P 3 "const_int_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1128 (clobber (reg:P 15))]
1129 "REGNO (operands[0]) == INTVAL (operands[3])"
1131 if (flag_delayed_branch)
1132 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1134 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1136 [(set (attr "type") (const_string "multi"))
1137 (set (attr "length")
1138 (if_then_else (eq_attr "delayed_branch" "true")
1143 ;; Integer move instructions
1145 (define_expand "movqi"
1146 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1147 (match_operand:QI 1 "general_operand" ""))]
1150 if (sparc_expand_move (QImode, operands))
1154 (define_insn "*movqi_insn"
1155 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1156 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1157 "(register_operand (operands[0], QImode)
1158 || register_or_zero_operand (operands[1], QImode))"
1163 [(set_attr "type" "*,load,store")
1164 (set_attr "us3load_type" "*,3cycle,*")])
1166 (define_expand "movhi"
1167 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1168 (match_operand:HI 1 "general_operand" ""))]
1171 if (sparc_expand_move (HImode, operands))
1175 (define_insn "*movhi_insn"
1176 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1177 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1178 "(register_operand (operands[0], HImode)
1179 || register_or_zero_operand (operands[1], HImode))"
1182 sethi\t%%hi(%a1), %0
1185 [(set_attr "type" "*,*,load,store")
1186 (set_attr "us3load_type" "*,*,3cycle,*")])
1188 ;; We always work with constants here.
1189 (define_insn "*movhi_lo_sum"
1190 [(set (match_operand:HI 0 "register_operand" "=r")
1191 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1192 (match_operand:HI 2 "small_int_operand" "I")))]
1196 (define_expand "movsi"
1197 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1198 (match_operand:SI 1 "general_operand" ""))]
1201 if (sparc_expand_move (SImode, operands))
1205 (define_insn "*movsi_insn"
1206 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d")
1207 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,f,m,f,J"))]
1208 "(register_operand (operands[0], SImode)
1209 || register_or_zero_operand (operands[1], SImode))"
1212 sethi\t%%hi(%a1), %0
1219 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")])
1221 (define_insn "*movsi_lo_sum"
1222 [(set (match_operand:SI 0 "register_operand" "=r")
1223 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1224 (match_operand:SI 2 "immediate_operand" "in")))]
1226 "or\t%1, %%lo(%a2), %0")
1228 (define_insn "*movsi_high"
1229 [(set (match_operand:SI 0 "register_operand" "=r")
1230 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1232 "sethi\t%%hi(%a1), %0")
1234 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1235 ;; so that CSE won't optimize the address computation away.
1236 (define_insn "movsi_lo_sum_pic"
1237 [(set (match_operand:SI 0 "register_operand" "=r")
1238 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1239 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1242 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1243 return "xor\t%1, %%gdop_lox10(%a2), %0";
1245 return "or\t%1, %%lo(%a2), %0";
1249 (define_insn "movsi_high_pic"
1250 [(set (match_operand:SI 0 "register_operand" "=r")
1251 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1252 "flag_pic && check_pic (1)"
1254 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1255 return "sethi\t%%gdop_hix22(%a1), %0";
1257 return "sethi\t%%hi(%a1), %0";
1261 (define_insn "movsi_pic_gotdata_op"
1262 [(set (match_operand:SI 0 "register_operand" "=r")
1263 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1264 (match_operand:SI 2 "register_operand" "r")
1265 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1266 "flag_pic && check_pic (1)"
1268 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1269 return "ld\t[%1 + %2], %0, %%gdop(%a3)";
1271 return "ld\t[%1 + %2], %0";
1274 [(set_attr "type" "load")])
1276 (define_expand "movsi_pic_label_ref"
1277 [(set (match_dup 3) (high:SI
1278 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1279 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1280 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1281 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1282 (set (match_operand:SI 0 "register_operand" "=r")
1283 (minus:SI (match_dup 5) (match_dup 4)))]
1286 crtl->uses_pic_offset_table = 1;
1287 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1288 if (!can_create_pseudo_p ())
1290 operands[3] = operands[0];
1291 operands[4] = operands[0];
1295 operands[3] = gen_reg_rtx (SImode);
1296 operands[4] = gen_reg_rtx (SImode);
1298 operands[5] = pic_offset_table_rtx;
1301 (define_insn "*movsi_high_pic_label_ref"
1302 [(set (match_operand:SI 0 "register_operand" "=r")
1304 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1305 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1307 "sethi\t%%hi(%a2-(%a1-.)), %0")
1309 (define_insn "*movsi_lo_sum_pic_label_ref"
1310 [(set (match_operand:SI 0 "register_operand" "=r")
1311 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1312 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1313 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1315 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1317 ;; Set up the PIC register for VxWorks.
1319 (define_expand "vxworks_load_got"
1321 (high:SI (match_dup 1)))
1323 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1325 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1326 "TARGET_VXWORKS_RTP"
1328 operands[0] = pic_offset_table_rtx;
1329 operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1330 operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1333 (define_expand "movdi"
1334 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1335 (match_operand:DI 1 "general_operand" ""))]
1338 if (sparc_expand_move (DImode, operands))
1342 ;; Be careful, fmovd does not exist when !v9.
1343 ;; We match MEM moves directly when we have correct even
1344 ;; numbered registers, but fall into splits otherwise.
1345 ;; The constraint ordering here is really important to
1346 ;; avoid insane problems in reload, especially for patterns
1349 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1350 ;; (const_int -5016)))
1354 (define_insn "*movdi_insn_sp32"
1355 [(set (match_operand:DI 0 "nonimmediate_operand"
1356 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1357 (match_operand:DI 1 "input_operand"
1358 " J,U,T,r,o,i,r, f, T, o, f, f"))]
1360 && (register_operand (operands[0], DImode)
1361 || register_or_zero_operand (operands[1], DImode))"
1375 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1376 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1378 (define_insn "*movdi_insn_sp32_v9"
1379 [(set (match_operand:DI 0 "nonimmediate_operand"
1380 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1381 (match_operand:DI 1 "input_operand"
1382 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1385 && (register_operand (operands[0], DImode)
1386 || register_or_zero_operand (operands[1], DImode))"
1403 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
1404 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
1405 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
1407 (define_insn "*movdi_insn_sp64"
1408 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b")
1409 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,e,W,e,J"))]
1411 && (register_operand (operands[0], DImode)
1412 || register_or_zero_operand (operands[1], DImode))"
1415 sethi\t%%hi(%a1), %0
1422 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")
1423 (set_attr "fptype" "*,*,*,*,double,*,*,double")])
1425 (define_expand "movdi_pic_label_ref"
1426 [(set (match_dup 3) (high:DI
1427 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1428 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1429 (set (match_dup 4) (lo_sum:DI (match_dup 3)
1430 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1431 (set (match_operand:DI 0 "register_operand" "=r")
1432 (minus:DI (match_dup 5) (match_dup 4)))]
1433 "TARGET_ARCH64 && flag_pic"
1435 crtl->uses_pic_offset_table = 1;
1436 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1437 if (!can_create_pseudo_p ())
1439 operands[3] = operands[0];
1440 operands[4] = operands[0];
1444 operands[3] = gen_reg_rtx (DImode);
1445 operands[4] = gen_reg_rtx (DImode);
1447 operands[5] = pic_offset_table_rtx;
1450 (define_insn "*movdi_high_pic_label_ref"
1451 [(set (match_operand:DI 0 "register_operand" "=r")
1453 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1454 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1455 "TARGET_ARCH64 && flag_pic"
1456 "sethi\t%%hi(%a2-(%a1-.)), %0")
1458 (define_insn "*movdi_lo_sum_pic_label_ref"
1459 [(set (match_operand:DI 0 "register_operand" "=r")
1460 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1461 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
1462 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1463 "TARGET_ARCH64 && flag_pic"
1464 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1466 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
1467 ;; in sparc.c to see what is going on here... PIC stuff comes first.
1469 (define_insn "movdi_lo_sum_pic"
1470 [(set (match_operand:DI 0 "register_operand" "=r")
1471 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1472 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1473 "TARGET_ARCH64 && flag_pic"
1475 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1476 return "xor\t%1, %%gdop_lox10(%a2), %0";
1478 return "or\t%1, %%lo(%a2), %0";
1482 (define_insn "movdi_high_pic"
1483 [(set (match_operand:DI 0 "register_operand" "=r")
1484 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1485 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1487 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1488 return "sethi\t%%gdop_hix22(%a1), %0";
1490 return "sethi\t%%hi(%a1), %0";
1494 (define_insn "movdi_pic_gotdata_op"
1495 [(set (match_operand:DI 0 "register_operand" "=r")
1496 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1497 (match_operand:DI 2 "register_operand" "r")
1498 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1499 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1501 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1502 return "ldx\t[%1 + %2], %0, %%gdop(%a3)";
1504 return "ldx\t[%1 + %2], %0";
1507 [(set_attr "type" "load")])
1509 (define_insn "*sethi_di_medlow_embmedany_pic"
1510 [(set (match_operand:DI 0 "register_operand" "=r")
1511 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
1512 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
1513 "sethi\t%%hi(%a1), %0")
1515 (define_insn "*sethi_di_medlow"
1516 [(set (match_operand:DI 0 "register_operand" "=r")
1517 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
1518 "TARGET_CM_MEDLOW && check_pic (1)"
1519 "sethi\t%%hi(%a1), %0")
1521 (define_insn "*losum_di_medlow"
1522 [(set (match_operand:DI 0 "register_operand" "=r")
1523 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1524 (match_operand:DI 2 "symbolic_operand" "")))]
1526 "or\t%1, %%lo(%a2), %0")
1528 (define_insn "seth44"
1529 [(set (match_operand:DI 0 "register_operand" "=r")
1530 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
1532 "sethi\t%%h44(%a1), %0")
1534 (define_insn "setm44"
1535 [(set (match_operand:DI 0 "register_operand" "=r")
1536 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1537 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
1539 "or\t%1, %%m44(%a2), %0")
1541 (define_insn "setl44"
1542 [(set (match_operand:DI 0 "register_operand" "=r")
1543 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1544 (match_operand:DI 2 "symbolic_operand" "")))]
1546 "or\t%1, %%l44(%a2), %0")
1548 (define_insn "sethh"
1549 [(set (match_operand:DI 0 "register_operand" "=r")
1550 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
1552 "sethi\t%%hh(%a1), %0")
1554 (define_insn "setlm"
1555 [(set (match_operand:DI 0 "register_operand" "=r")
1556 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
1558 "sethi\t%%lm(%a1), %0")
1560 (define_insn "sethm"
1561 [(set (match_operand:DI 0 "register_operand" "=r")
1562 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1563 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
1565 "or\t%1, %%hm(%a2), %0")
1567 (define_insn "setlo"
1568 [(set (match_operand:DI 0 "register_operand" "=r")
1569 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1570 (match_operand:DI 2 "symbolic_operand" "")))]
1572 "or\t%1, %%lo(%a2), %0")
1574 (define_insn "embmedany_sethi"
1575 [(set (match_operand:DI 0 "register_operand" "=r")
1576 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
1577 "TARGET_CM_EMBMEDANY && check_pic (1)"
1578 "sethi\t%%hi(%a1), %0")
1580 (define_insn "embmedany_losum"
1581 [(set (match_operand:DI 0 "register_operand" "=r")
1582 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1583 (match_operand:DI 2 "data_segment_operand" "")))]
1584 "TARGET_CM_EMBMEDANY"
1585 "add\t%1, %%lo(%a2), %0")
1587 (define_insn "embmedany_brsum"
1588 [(set (match_operand:DI 0 "register_operand" "=r")
1589 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
1590 "TARGET_CM_EMBMEDANY"
1593 (define_insn "embmedany_textuhi"
1594 [(set (match_operand:DI 0 "register_operand" "=r")
1595 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
1596 "TARGET_CM_EMBMEDANY && check_pic (1)"
1597 "sethi\t%%uhi(%a1), %0")
1599 (define_insn "embmedany_texthi"
1600 [(set (match_operand:DI 0 "register_operand" "=r")
1601 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
1602 "TARGET_CM_EMBMEDANY && check_pic (1)"
1603 "sethi\t%%hi(%a1), %0")
1605 (define_insn "embmedany_textulo"
1606 [(set (match_operand:DI 0 "register_operand" "=r")
1607 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1608 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
1609 "TARGET_CM_EMBMEDANY"
1610 "or\t%1, %%ulo(%a2), %0")
1612 (define_insn "embmedany_textlo"
1613 [(set (match_operand:DI 0 "register_operand" "=r")
1614 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1615 (match_operand:DI 2 "text_segment_operand" "")))]
1616 "TARGET_CM_EMBMEDANY"
1617 "or\t%1, %%lo(%a2), %0")
1619 ;; Now some patterns to help reload out a bit.
1620 (define_expand "reload_indi"
1621 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1622 (match_operand:DI 1 "immediate_operand" "")
1623 (match_operand:TI 2 "register_operand" "=&r")])]
1625 || TARGET_CM_EMBMEDANY)
1628 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1632 (define_expand "reload_outdi"
1633 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1634 (match_operand:DI 1 "immediate_operand" "")
1635 (match_operand:TI 2 "register_operand" "=&r")])]
1637 || TARGET_CM_EMBMEDANY)
1640 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1644 ;; Split up putting CONSTs and REGs into DI regs when !arch64
1646 [(set (match_operand:DI 0 "register_operand" "")
1647 (match_operand:DI 1 "const_int_operand" ""))]
1648 "! TARGET_ARCH64 && reload_completed"
1649 [(clobber (const_int 0))]
1651 #if HOST_BITS_PER_WIDE_INT == 32
1652 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1653 (INTVAL (operands[1]) < 0) ?
1656 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1659 unsigned int low, high;
1661 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
1662 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
1663 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
1665 /* Slick... but this trick loses if this subreg constant part
1666 can be done in one insn. */
1668 && ! SPARC_SETHI32_P (high)
1669 && ! SPARC_SIMM13_P (high))
1670 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1671 gen_highpart (SImode, operands[0])));
1673 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
1679 [(set (match_operand:DI 0 "register_operand" "")
1680 (match_operand:DI 1 "const_double_operand" ""))]
1684 && ((GET_CODE (operands[0]) == REG
1685 && REGNO (operands[0]) < 32)
1686 || (GET_CODE (operands[0]) == SUBREG
1687 && GET_CODE (SUBREG_REG (operands[0])) == REG
1688 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1689 [(clobber (const_int 0))]
1691 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1692 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
1694 /* Slick... but this trick loses if this subreg constant part
1695 can be done in one insn. */
1696 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
1697 && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
1698 && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
1700 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1701 gen_highpart (SImode, operands[0])));
1705 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1706 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
1712 [(set (match_operand:DI 0 "register_operand" "")
1713 (match_operand:DI 1 "register_operand" ""))]
1717 && ((GET_CODE (operands[0]) == REG
1718 && REGNO (operands[0]) < 32)
1719 || (GET_CODE (operands[0]) == SUBREG
1720 && GET_CODE (SUBREG_REG (operands[0])) == REG
1721 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1722 [(clobber (const_int 0))]
1724 rtx set_dest = operands[0];
1725 rtx set_src = operands[1];
1729 dest1 = gen_highpart (SImode, set_dest);
1730 dest2 = gen_lowpart (SImode, set_dest);
1731 src1 = gen_highpart (SImode, set_src);
1732 src2 = gen_lowpart (SImode, set_src);
1734 /* Now emit using the real source and destination we found, swapping
1735 the order if we detect overlap. */
1736 if (reg_overlap_mentioned_p (dest1, src2))
1738 emit_insn (gen_movsi (dest2, src2));
1739 emit_insn (gen_movsi (dest1, src1));
1743 emit_insn (gen_movsi (dest1, src1));
1744 emit_insn (gen_movsi (dest2, src2));
1749 ;; Now handle the cases of memory moves from/to non-even
1750 ;; DI mode register pairs.
1752 [(set (match_operand:DI 0 "register_operand" "")
1753 (match_operand:DI 1 "memory_operand" ""))]
1756 && sparc_splitdi_legitimate (operands[0], operands[1]))"
1757 [(clobber (const_int 0))]
1759 rtx word0 = adjust_address (operands[1], SImode, 0);
1760 rtx word1 = adjust_address (operands[1], SImode, 4);
1761 rtx high_part = gen_highpart (SImode, operands[0]);
1762 rtx low_part = gen_lowpart (SImode, operands[0]);
1764 if (reg_overlap_mentioned_p (high_part, word1))
1766 emit_insn (gen_movsi (low_part, word1));
1767 emit_insn (gen_movsi (high_part, word0));
1771 emit_insn (gen_movsi (high_part, word0));
1772 emit_insn (gen_movsi (low_part, word1));
1778 [(set (match_operand:DI 0 "memory_operand" "")
1779 (match_operand:DI 1 "register_operand" ""))]
1782 && sparc_splitdi_legitimate (operands[1], operands[0]))"
1783 [(clobber (const_int 0))]
1785 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
1786 gen_highpart (SImode, operands[1])));
1787 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
1788 gen_lowpart (SImode, operands[1])));
1793 [(set (match_operand:DI 0 "memory_operand" "")
1794 (match_operand:DI 1 "const_zero_operand" ""))]
1798 && ! mem_min_alignment (operands[0], 8)))
1799 && offsettable_memref_p (operands[0])"
1800 [(clobber (const_int 0))]
1802 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
1803 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
1808 ;; Floating point and vector move instructions
1810 ;; Yes, you guessed it right, the former movsf expander.
1811 (define_expand "mov<V32:mode>"
1812 [(set (match_operand:V32 0 "nonimmediate_operand" "")
1813 (match_operand:V32 1 "general_operand" ""))]
1814 "<V32:MODE>mode == SFmode || TARGET_VIS"
1816 if (sparc_expand_move (<V32:MODE>mode, operands))
1820 (define_insn "*movsf_insn"
1821 [(set (match_operand:V32 0 "nonimmediate_operand" "=d,f,*r,*r,*r,f,*r,m,m")
1822 (match_operand:V32 1 "input_operand" "GY,f,*rRY,Q,S,m,m,f,*rGY"))]
1824 && (register_operand (operands[0], <V32:MODE>mode)
1825 || register_or_zero_operand (operands[1], <V32:MODE>mode))"
1827 if (GET_CODE (operands[1]) == CONST_DOUBLE
1828 && (which_alternative == 2
1829 || which_alternative == 3
1830 || which_alternative == 4))
1835 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1836 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1837 operands[1] = GEN_INT (i);
1840 switch (which_alternative)
1843 return "fzeros\t%0";
1845 return "fmovs\t%1, %0";
1847 return "mov\t%1, %0";
1849 return "sethi\t%%hi(%a1), %0";
1854 return "ld\t%1, %0";
1857 return "st\t%r1, %0";
1862 [(set_attr "type" "fga,fpmove,*,*,*,fpload,load,fpstore,store")])
1864 ;; Exactly the same as above, except that all `f' cases are deleted.
1865 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1868 (define_insn "*movsf_insn_no_fpu"
1869 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
1870 (match_operand:SF 1 "input_operand" "rR,Q,S,m,rG"))]
1872 && (register_operand (operands[0], SFmode)
1873 || register_or_zero_operand (operands[1], SFmode))"
1875 if (GET_CODE (operands[1]) == CONST_DOUBLE
1876 && (which_alternative == 0
1877 || which_alternative == 1
1878 || which_alternative == 2))
1883 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1884 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1885 operands[1] = GEN_INT (i);
1888 switch (which_alternative)
1891 return "mov\t%1, %0";
1893 return "sethi\t%%hi(%a1), %0";
1897 return "ld\t%1, %0";
1899 return "st\t%r1, %0";
1904 [(set_attr "type" "*,*,*,load,store")])
1906 ;; The following 3 patterns build SFmode constants in integer registers.
1908 (define_insn "*movsf_lo_sum"
1909 [(set (match_operand:SF 0 "register_operand" "=r")
1910 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
1911 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
1917 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
1918 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1919 operands[2] = GEN_INT (i);
1920 return "or\t%1, %%lo(%a2), %0";
1923 (define_insn "*movsf_high"
1924 [(set (match_operand:SF 0 "register_operand" "=r")
1925 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
1931 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1932 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1933 operands[1] = GEN_INT (i);
1934 return "sethi\t%%hi(%1), %0";
1938 [(set (match_operand:SF 0 "register_operand" "")
1939 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
1940 "REG_P (operands[0]) && REGNO (operands[0]) < 32"
1941 [(set (match_dup 0) (high:SF (match_dup 1)))
1942 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
1944 ;; Yes, you again guessed it right, the former movdf expander.
1945 (define_expand "mov<V64:mode>"
1946 [(set (match_operand:V64 0 "nonimmediate_operand" "")
1947 (match_operand:V64 1 "general_operand" ""))]
1948 "<V64:MODE>mode == DFmode || TARGET_VIS"
1950 if (sparc_expand_move (<V64:MODE>mode, operands))
1954 ;; Be careful, fmovd does not exist when !v9.
1955 (define_insn "*movdf_insn_sp32"
1956 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
1957 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
1960 && (register_operand (operands[0], DFmode)
1961 || register_or_zero_operand (operands[1], DFmode))"
1973 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
1974 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
1976 (define_insn "*movdf_insn_sp32_no_fpu"
1977 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
1978 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
1981 && (register_operand (operands[0], DFmode)
1982 || register_or_zero_operand (operands[1], DFmode))"
1989 [(set_attr "type" "load,store,*,*,*")
1990 (set_attr "length" "*,*,2,2,2")])
1992 ;; We have available v9 double floats but not 64-bit integer registers.
1993 (define_insn "*movdf_insn_sp32_v9"
1994 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o")
1995 (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYDF,*rGYf"))]
1999 && (register_operand (operands[0], <V64:MODE>mode)
2000 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2012 [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
2013 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2014 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2016 (define_insn "*movdf_insn_sp32_v9_no_fpu"
2017 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2018 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2022 && (register_operand (operands[0], DFmode)
2023 || register_or_zero_operand (operands[1], DFmode))"
2030 [(set_attr "type" "load,store,store,*,*")
2031 (set_attr "length" "*,*,*,2,2")])
2033 ;; We have available both v9 double floats and 64-bit integer registers.
2034 (define_insn "*movdf_insn_sp64"
2035 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r")
2036 (match_operand:V64 1 "input_operand" "GY,e,W#F,e,*rGY,m,*rGY,DF"))]
2039 && (register_operand (operands[0], <V64:MODE>mode)
2040 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2050 [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
2051 (set_attr "length" "*,*,*,*,*,*,*,2")
2052 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
2054 (define_insn "*movdf_insn_sp64_no_fpu"
2055 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2056 (match_operand:DF 1 "input_operand" "r,m,rG"))]
2059 && (register_operand (operands[0], DFmode)
2060 || register_or_zero_operand (operands[1], DFmode))"
2065 [(set_attr "type" "*,load,store")])
2067 ;; This pattern builds V64mode constants in integer registers.
2069 [(set (match_operand:V64 0 "register_operand" "")
2070 (match_operand:V64 1 "const_double_or_vector_operand" ""))]
2072 && (GET_CODE (operands[0]) == REG
2073 && REGNO (operands[0]) < 32)
2074 && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2075 && reload_completed"
2076 [(clobber (const_int 0))]
2078 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2082 #if HOST_BITS_PER_WIDE_INT == 32
2085 enum machine_mode mode = GET_MODE (operands[1]);
2086 rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2087 emit_insn (gen_movdi (operands[0], tem));
2092 enum machine_mode mode = GET_MODE (operands[1]);
2093 rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2094 rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2096 gcc_assert (GET_CODE (hi) == CONST_INT);
2097 gcc_assert (GET_CODE (lo) == CONST_INT);
2099 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2101 /* Slick... but this trick loses if this subreg constant part
2102 can be done in one insn. */
2104 && ! SPARC_SETHI32_P (INTVAL (hi))
2105 && ! SPARC_SIMM13_P (INTVAL (hi)))
2107 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2108 gen_highpart (SImode, operands[0])));
2112 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2118 ;; Ok, now the splits to handle all the multi insn and
2119 ;; mis-aligned memory address cases.
2120 ;; In these splits please take note that we must be
2121 ;; careful when V9 but not ARCH64 because the integer
2122 ;; register DFmode cases must be handled.
2124 [(set (match_operand:V64 0 "register_operand" "")
2125 (match_operand:V64 1 "register_operand" ""))]
2128 && ((GET_CODE (operands[0]) == REG
2129 && REGNO (operands[0]) < 32)
2130 || (GET_CODE (operands[0]) == SUBREG
2131 && GET_CODE (SUBREG_REG (operands[0])) == REG
2132 && REGNO (SUBREG_REG (operands[0])) < 32))))
2133 && reload_completed"
2134 [(clobber (const_int 0))]
2136 rtx set_dest = operands[0];
2137 rtx set_src = operands[1];
2140 enum machine_mode half_mode;
2142 /* We can be expanded for DFmode or integral vector modes. */
2143 if (<V64:MODE>mode == DFmode)
2148 dest1 = gen_highpart (half_mode, set_dest);
2149 dest2 = gen_lowpart (half_mode, set_dest);
2150 src1 = gen_highpart (half_mode, set_src);
2151 src2 = gen_lowpart (half_mode, set_src);
2153 /* Now emit using the real source and destination we found, swapping
2154 the order if we detect overlap. */
2155 if (reg_overlap_mentioned_p (dest1, src2))
2157 emit_move_insn_1 (dest2, src2);
2158 emit_move_insn_1 (dest1, src1);
2162 emit_move_insn_1 (dest1, src1);
2163 emit_move_insn_1 (dest2, src2);
2169 [(set (match_operand:V64 0 "register_operand" "")
2170 (match_operand:V64 1 "memory_operand" ""))]
2173 && (((REGNO (operands[0]) % 2) != 0)
2174 || ! mem_min_alignment (operands[1], 8))
2175 && offsettable_memref_p (operands[1])"
2176 [(clobber (const_int 0))]
2178 enum machine_mode half_mode;
2181 /* We can be expanded for DFmode or integral vector modes. */
2182 if (<V64:MODE>mode == DFmode)
2187 word0 = adjust_address (operands[1], half_mode, 0);
2188 word1 = adjust_address (operands[1], half_mode, 4);
2190 if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
2192 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2193 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2197 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2198 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2204 [(set (match_operand:V64 0 "memory_operand" "")
2205 (match_operand:V64 1 "register_operand" ""))]
2208 && (((REGNO (operands[1]) % 2) != 0)
2209 || ! mem_min_alignment (operands[0], 8))
2210 && offsettable_memref_p (operands[0])"
2211 [(clobber (const_int 0))]
2213 enum machine_mode half_mode;
2216 /* We can be expanded for DFmode or integral vector modes. */
2217 if (<V64:MODE>mode == DFmode)
2222 word0 = adjust_address (operands[0], half_mode, 0);
2223 word1 = adjust_address (operands[0], half_mode, 4);
2225 emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
2226 emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
2231 [(set (match_operand:V64 0 "memory_operand" "")
2232 (match_operand:V64 1 "const_zero_operand" ""))]
2236 && ! mem_min_alignment (operands[0], 8)))
2237 && offsettable_memref_p (operands[0])"
2238 [(clobber (const_int 0))]
2240 enum machine_mode half_mode;
2243 /* We can be expanded for DFmode or integral vector modes. */
2244 if (<V64:MODE>mode == DFmode)
2249 dest1 = adjust_address (operands[0], half_mode, 0);
2250 dest2 = adjust_address (operands[0], half_mode, 4);
2252 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2253 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2258 [(set (match_operand:V64 0 "register_operand" "")
2259 (match_operand:V64 1 "const_zero_operand" ""))]
2262 && ((GET_CODE (operands[0]) == REG
2263 && REGNO (operands[0]) < 32)
2264 || (GET_CODE (operands[0]) == SUBREG
2265 && GET_CODE (SUBREG_REG (operands[0])) == REG
2266 && REGNO (SUBREG_REG (operands[0])) < 32))"
2267 [(clobber (const_int 0))]
2269 enum machine_mode half_mode;
2270 rtx set_dest = operands[0];
2273 /* We can be expanded for DFmode or integral vector modes. */
2274 if (<V64:MODE>mode == DFmode)
2279 dest1 = gen_highpart (half_mode, set_dest);
2280 dest2 = gen_lowpart (half_mode, set_dest);
2281 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2282 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2286 (define_expand "movtf"
2287 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2288 (match_operand:TF 1 "general_operand" ""))]
2291 if (sparc_expand_move (TFmode, operands))
2295 (define_insn "*movtf_insn_sp32"
2296 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2297 (match_operand:TF 1 "input_operand" "G,oe,GeUr,o,roG"))]
2300 && (register_operand (operands[0], TFmode)
2301 || register_or_zero_operand (operands[1], TFmode))"
2303 [(set_attr "length" "4")])
2305 ;; Exactly the same as above, except that all `e' cases are deleted.
2306 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2309 (define_insn "*movtf_insn_sp32_no_fpu"
2310 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2311 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
2314 && (register_operand (operands[0], TFmode)
2315 || register_or_zero_operand (operands[1], TFmode))"
2317 [(set_attr "length" "4")])
2319 (define_insn "*movtf_insn_sp64"
2320 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2321 (match_operand:TF 1 "input_operand" "G,oe,Ger,roG"))]
2324 && ! TARGET_HARD_QUAD
2325 && (register_operand (operands[0], TFmode)
2326 || register_or_zero_operand (operands[1], TFmode))"
2328 [(set_attr "length" "2")])
2330 (define_insn "*movtf_insn_sp64_hq"
2331 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2332 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
2336 && (register_operand (operands[0], TFmode)
2337 || register_or_zero_operand (operands[1], TFmode))"
2345 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2346 (set_attr "length" "2,*,*,*,2,2")])
2348 (define_insn "*movtf_insn_sp64_no_fpu"
2349 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2350 (match_operand:TF 1 "input_operand" "orG,rG"))]
2353 && (register_operand (operands[0], TFmode)
2354 || register_or_zero_operand (operands[1], TFmode))"
2356 [(set_attr "length" "2")])
2358 ;; Now all the splits to handle multi-insn TF mode moves.
2360 [(set (match_operand:TF 0 "register_operand" "")
2361 (match_operand:TF 1 "register_operand" ""))]
2365 && ! TARGET_HARD_QUAD)
2366 || ! fp_register_operand (operands[0], TFmode))"
2367 [(clobber (const_int 0))]
2369 rtx set_dest = operands[0];
2370 rtx set_src = operands[1];
2374 dest1 = gen_df_reg (set_dest, 0);
2375 dest2 = gen_df_reg (set_dest, 1);
2376 src1 = gen_df_reg (set_src, 0);
2377 src2 = gen_df_reg (set_src, 1);
2379 /* Now emit using the real source and destination we found, swapping
2380 the order if we detect overlap. */
2381 if (reg_overlap_mentioned_p (dest1, src2))
2383 emit_insn (gen_movdf (dest2, src2));
2384 emit_insn (gen_movdf (dest1, src1));
2388 emit_insn (gen_movdf (dest1, src1));
2389 emit_insn (gen_movdf (dest2, src2));
2395 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2396 (match_operand:TF 1 "const_zero_operand" ""))]
2398 [(clobber (const_int 0))]
2400 rtx set_dest = operands[0];
2403 switch (GET_CODE (set_dest))
2406 dest1 = gen_df_reg (set_dest, 0);
2407 dest2 = gen_df_reg (set_dest, 1);
2410 dest1 = adjust_address (set_dest, DFmode, 0);
2411 dest2 = adjust_address (set_dest, DFmode, 8);
2417 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2418 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2423 [(set (match_operand:TF 0 "register_operand" "")
2424 (match_operand:TF 1 "memory_operand" ""))]
2426 && offsettable_memref_p (operands[1])
2428 || ! TARGET_HARD_QUAD
2429 || ! fp_register_operand (operands[0], TFmode)))"
2430 [(clobber (const_int 0))]
2432 rtx word0 = adjust_address (operands[1], DFmode, 0);
2433 rtx word1 = adjust_address (operands[1], DFmode, 8);
2434 rtx set_dest, dest1, dest2;
2436 set_dest = operands[0];
2438 dest1 = gen_df_reg (set_dest, 0);
2439 dest2 = gen_df_reg (set_dest, 1);
2441 /* Now output, ordering such that we don't clobber any registers
2442 mentioned in the address. */
2443 if (reg_overlap_mentioned_p (dest1, word1))
2446 emit_insn (gen_movdf (dest2, word1));
2447 emit_insn (gen_movdf (dest1, word0));
2451 emit_insn (gen_movdf (dest1, word0));
2452 emit_insn (gen_movdf (dest2, word1));
2458 [(set (match_operand:TF 0 "memory_operand" "")
2459 (match_operand:TF 1 "register_operand" ""))]
2461 && offsettable_memref_p (operands[0])
2463 || ! TARGET_HARD_QUAD
2464 || ! fp_register_operand (operands[1], TFmode)))"
2465 [(clobber (const_int 0))]
2467 rtx set_src = operands[1];
2469 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2470 gen_df_reg (set_src, 0)));
2471 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2472 gen_df_reg (set_src, 1)));
2477 ;; SPARC-V9 conditional move instructions
2479 ;; We can handle larger constants here for some flavors, but for now we keep
2480 ;; it simple and only allow those constants supported by all flavors.
2481 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2482 ;; 3 contains the constant if one is present, but we handle either for
2483 ;; generality (sparc.c puts a constant in operand 2).
2485 (define_expand "mov<I:mode>cc"
2486 [(set (match_operand:I 0 "register_operand" "")
2487 (if_then_else:I (match_operand 1 "comparison_operator" "")
2488 (match_operand:I 2 "arith10_operand" "")
2489 (match_operand:I 3 "arith10_operand" "")))]
2490 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2492 enum rtx_code code = GET_CODE (operands[1]);
2495 if (GET_MODE (XEXP (operands[1], 0)) == DImode
2499 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2501 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2502 GET_CODE (operands[1]));
2504 if (XEXP (operands[1], 1) == const0_rtx
2505 && GET_CODE (XEXP (operands[1], 0)) == REG
2506 && GET_MODE (XEXP (operands[1], 0)) == DImode
2507 && v9_regcmp_p (code))
2508 cc_reg = XEXP (operands[1], 0);
2510 cc_reg = gen_compare_reg (operands[1]);
2512 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2515 (define_expand "mov<F:mode>cc"
2516 [(set (match_operand:F 0 "register_operand" "")
2517 (if_then_else:F (match_operand 1 "comparison_operator" "")
2518 (match_operand:F 2 "register_operand" "")
2519 (match_operand:F 3 "register_operand" "")))]
2520 "TARGET_V9 && TARGET_FPU"
2522 enum rtx_code code = GET_CODE (operands[1]);
2525 if (GET_MODE (XEXP (operands[1], 0)) == DImode
2529 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2531 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2532 GET_CODE (operands[1]));
2534 if (XEXP (operands[1], 1) == const0_rtx
2535 && GET_CODE (XEXP (operands[1], 0)) == REG
2536 && GET_MODE (XEXP (operands[1], 0)) == DImode
2537 && v9_regcmp_p (code))
2538 cc_reg = XEXP (operands[1], 0);
2540 cc_reg = gen_compare_reg (operands[1]);
2542 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2545 ;; Conditional move define_insns
2547 (define_insn "*mov<I:mode>_cc_v9"
2548 [(set (match_operand:I 0 "register_operand" "=r,r")
2549 (if_then_else:I (match_operator 1 "comparison_operator"
2550 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2552 (match_operand:I 3 "arith11_operand" "rL,0")
2553 (match_operand:I 4 "arith11_operand" "0,rL")))]
2554 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2557 mov%c1\t%x2, %4, %0"
2558 [(set_attr "type" "cmove")])
2560 (define_insn "*mov<I:mode>_cc_reg_sp64"
2561 [(set (match_operand:I 0 "register_operand" "=r,r")
2562 (if_then_else:I (match_operator 1 "v9_register_compare_operator"
2563 [(match_operand:DI 2 "register_operand" "r,r")
2565 (match_operand:I 3 "arith10_operand" "rM,0")
2566 (match_operand:I 4 "arith10_operand" "0,rM")))]
2569 movr%D1\t%2, %r3, %0
2570 movr%d1\t%2, %r4, %0"
2571 [(set_attr "type" "cmove")])
2573 (define_insn "*movsf_cc_v9"
2574 [(set (match_operand:SF 0 "register_operand" "=f,f")
2575 (if_then_else:SF (match_operator 1 "comparison_operator"
2576 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2578 (match_operand:SF 3 "register_operand" "f,0")
2579 (match_operand:SF 4 "register_operand" "0,f")))]
2580 "TARGET_V9 && TARGET_FPU"
2582 fmovs%C1\t%x2, %3, %0
2583 fmovs%c1\t%x2, %4, %0"
2584 [(set_attr "type" "fpcmove")])
2586 (define_insn "*movsf_cc_reg_sp64"
2587 [(set (match_operand:SF 0 "register_operand" "=f,f")
2588 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
2589 [(match_operand:DI 2 "register_operand" "r,r")
2591 (match_operand:SF 3 "register_operand" "f,0")
2592 (match_operand:SF 4 "register_operand" "0,f")))]
2593 "TARGET_ARCH64 && TARGET_FPU"
2595 fmovrs%D1\t%2, %3, %0
2596 fmovrs%d1\t%2, %4, %0"
2597 [(set_attr "type" "fpcrmove")])
2599 ;; Named because invoked by movtf_cc_v9
2600 (define_insn "movdf_cc_v9"
2601 [(set (match_operand:DF 0 "register_operand" "=e,e")
2602 (if_then_else:DF (match_operator 1 "comparison_operator"
2603 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2605 (match_operand:DF 3 "register_operand" "e,0")
2606 (match_operand:DF 4 "register_operand" "0,e")))]
2607 "TARGET_V9 && TARGET_FPU"
2609 fmovd%C1\t%x2, %3, %0
2610 fmovd%c1\t%x2, %4, %0"
2611 [(set_attr "type" "fpcmove")
2612 (set_attr "fptype" "double")])
2614 ;; Named because invoked by movtf_cc_reg_sp64
2615 (define_insn "movdf_cc_reg_sp64"
2616 [(set (match_operand:DF 0 "register_operand" "=e,e")
2617 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
2618 [(match_operand:DI 2 "register_operand" "r,r")
2620 (match_operand:DF 3 "register_operand" "e,0")
2621 (match_operand:DF 4 "register_operand" "0,e")))]
2622 "TARGET_ARCH64 && TARGET_FPU"
2624 fmovrd%D1\t%2, %3, %0
2625 fmovrd%d1\t%2, %4, %0"
2626 [(set_attr "type" "fpcrmove")
2627 (set_attr "fptype" "double")])
2629 (define_insn "*movtf_cc_hq_v9"
2630 [(set (match_operand:TF 0 "register_operand" "=e,e")
2631 (if_then_else:TF (match_operator 1 "comparison_operator"
2632 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2634 (match_operand:TF 3 "register_operand" "e,0")
2635 (match_operand:TF 4 "register_operand" "0,e")))]
2636 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2638 fmovq%C1\t%x2, %3, %0
2639 fmovq%c1\t%x2, %4, %0"
2640 [(set_attr "type" "fpcmove")])
2642 (define_insn "*movtf_cc_reg_hq_sp64"
2643 [(set (match_operand:TF 0 "register_operand" "=e,e")
2644 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2645 [(match_operand:DI 2 "register_operand" "r,r")
2647 (match_operand:TF 3 "register_operand" "e,0")
2648 (match_operand:TF 4 "register_operand" "0,e")))]
2649 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
2651 fmovrq%D1\t%2, %3, %0
2652 fmovrq%d1\t%2, %4, %0"
2653 [(set_attr "type" "fpcrmove")])
2655 (define_insn_and_split "*movtf_cc_v9"
2656 [(set (match_operand:TF 0 "register_operand" "=e,e")
2657 (if_then_else:TF (match_operator 1 "comparison_operator"
2658 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2660 (match_operand:TF 3 "register_operand" "e,0")
2661 (match_operand:TF 4 "register_operand" "0,e")))]
2662 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
2664 "&& reload_completed"
2665 [(clobber (const_int 0))]
2667 rtx set_dest = operands[0];
2668 rtx set_srca = operands[3];
2669 rtx set_srcb = operands[4];
2670 int third = rtx_equal_p (set_dest, set_srca);
2672 rtx srca1, srca2, srcb1, srcb2;
2674 dest1 = gen_df_reg (set_dest, 0);
2675 dest2 = gen_df_reg (set_dest, 1);
2676 srca1 = gen_df_reg (set_srca, 0);
2677 srca2 = gen_df_reg (set_srca, 1);
2678 srcb1 = gen_df_reg (set_srcb, 0);
2679 srcb2 = gen_df_reg (set_srcb, 1);
2681 /* Now emit using the real source and destination we found, swapping
2682 the order if we detect overlap. */
2683 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2684 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2686 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2687 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2691 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2692 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2696 [(set_attr "length" "2")])
2698 (define_insn_and_split "*movtf_cc_reg_sp64"
2699 [(set (match_operand:TF 0 "register_operand" "=e,e")
2700 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2701 [(match_operand:DI 2 "register_operand" "r,r")
2703 (match_operand:TF 3 "register_operand" "e,0")
2704 (match_operand:TF 4 "register_operand" "0,e")))]
2705 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
2707 "&& reload_completed"
2708 [(clobber (const_int 0))]
2710 rtx set_dest = operands[0];
2711 rtx set_srca = operands[3];
2712 rtx set_srcb = operands[4];
2713 int third = rtx_equal_p (set_dest, set_srca);
2715 rtx srca1, srca2, srcb1, srcb2;
2717 dest1 = gen_df_reg (set_dest, 0);
2718 dest2 = gen_df_reg (set_dest, 1);
2719 srca1 = gen_df_reg (set_srca, 0);
2720 srca2 = gen_df_reg (set_srca, 1);
2721 srcb1 = gen_df_reg (set_srcb, 0);
2722 srcb2 = gen_df_reg (set_srcb, 1);
2724 /* Now emit using the real source and destination we found, swapping
2725 the order if we detect overlap. */
2726 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2727 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2729 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2730 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2734 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2735 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2739 [(set_attr "length" "2")])
2742 ;; Zero-extension instructions
2744 ;; These patterns originally accepted general_operands, however, slightly
2745 ;; better code is generated by only accepting register_operands, and then
2746 ;; letting combine generate the ldu[hb] insns.
2748 (define_expand "zero_extendhisi2"
2749 [(set (match_operand:SI 0 "register_operand" "")
2750 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2753 rtx temp = gen_reg_rtx (SImode);
2754 rtx shift_16 = GEN_INT (16);
2755 int op1_subbyte = 0;
2757 if (GET_CODE (operand1) == SUBREG)
2759 op1_subbyte = SUBREG_BYTE (operand1);
2760 op1_subbyte /= GET_MODE_SIZE (SImode);
2761 op1_subbyte *= GET_MODE_SIZE (SImode);
2762 operand1 = XEXP (operand1, 0);
2765 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2767 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2771 (define_insn "*zero_extendhisi2_insn"
2772 [(set (match_operand:SI 0 "register_operand" "=r")
2773 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2776 [(set_attr "type" "load")
2777 (set_attr "us3load_type" "3cycle")])
2779 (define_expand "zero_extendqihi2"
2780 [(set (match_operand:HI 0 "register_operand" "")
2781 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2785 (define_insn "*zero_extendqihi2_insn"
2786 [(set (match_operand:HI 0 "register_operand" "=r,r")
2787 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
2788 "GET_CODE (operands[1]) != CONST_INT"
2792 [(set_attr "type" "*,load")
2793 (set_attr "us3load_type" "*,3cycle")])
2795 (define_expand "zero_extendqisi2"
2796 [(set (match_operand:SI 0 "register_operand" "")
2797 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2801 (define_insn "*zero_extendqisi2_insn"
2802 [(set (match_operand:SI 0 "register_operand" "=r,r")
2803 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
2804 "GET_CODE (operands[1]) != CONST_INT"
2808 [(set_attr "type" "*,load")
2809 (set_attr "us3load_type" "*,3cycle")])
2811 (define_expand "zero_extendqidi2"
2812 [(set (match_operand:DI 0 "register_operand" "")
2813 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2817 (define_insn "*zero_extendqidi2_insn"
2818 [(set (match_operand:DI 0 "register_operand" "=r,r")
2819 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
2820 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2824 [(set_attr "type" "*,load")
2825 (set_attr "us3load_type" "*,3cycle")])
2827 (define_expand "zero_extendhidi2"
2828 [(set (match_operand:DI 0 "register_operand" "")
2829 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2832 rtx temp = gen_reg_rtx (DImode);
2833 rtx shift_48 = GEN_INT (48);
2834 int op1_subbyte = 0;
2836 if (GET_CODE (operand1) == SUBREG)
2838 op1_subbyte = SUBREG_BYTE (operand1);
2839 op1_subbyte /= GET_MODE_SIZE (DImode);
2840 op1_subbyte *= GET_MODE_SIZE (DImode);
2841 operand1 = XEXP (operand1, 0);
2844 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
2846 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
2850 (define_insn "*zero_extendhidi2_insn"
2851 [(set (match_operand:DI 0 "register_operand" "=r")
2852 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2855 [(set_attr "type" "load")
2856 (set_attr "us3load_type" "3cycle")])
2858 ;; ??? Write truncdisi pattern using sra?
2860 (define_expand "zero_extendsidi2"
2861 [(set (match_operand:DI 0 "register_operand" "")
2862 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
2866 (define_insn "*zero_extendsidi2_insn_sp64"
2867 [(set (match_operand:DI 0 "register_operand" "=r,r")
2868 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
2869 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2873 [(set_attr "type" "shift,load")])
2875 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
2876 [(set (match_operand:DI 0 "register_operand" "=r")
2877 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
2880 "&& reload_completed"
2881 [(set (match_dup 2) (match_dup 3))
2882 (set (match_dup 4) (match_dup 5))]
2886 dest1 = gen_highpart (SImode, operands[0]);
2887 dest2 = gen_lowpart (SImode, operands[0]);
2889 /* Swap the order in case of overlap. */
2890 if (REGNO (dest1) == REGNO (operands[1]))
2892 operands[2] = dest2;
2893 operands[3] = operands[1];
2894 operands[4] = dest1;
2895 operands[5] = const0_rtx;
2899 operands[2] = dest1;
2900 operands[3] = const0_rtx;
2901 operands[4] = dest2;
2902 operands[5] = operands[1];
2905 [(set_attr "length" "2")])
2907 ;; Simplify comparisons of extended values.
2909 (define_insn "*cmp_zero_extendqisi2"
2911 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
2914 "andcc\t%0, 0xff, %%g0"
2915 [(set_attr "type" "compare")])
2917 (define_insn "*cmp_zero_qi"
2919 (compare:CC (match_operand:QI 0 "register_operand" "r")
2922 "andcc\t%0, 0xff, %%g0"
2923 [(set_attr "type" "compare")])
2925 (define_insn "*cmp_zero_extendqisi2_set"
2927 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
2929 (set (match_operand:SI 0 "register_operand" "=r")
2930 (zero_extend:SI (match_dup 1)))]
2932 "andcc\t%1, 0xff, %0"
2933 [(set_attr "type" "compare")])
2935 (define_insn "*cmp_zero_extendqisi2_andcc_set"
2937 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
2940 (set (match_operand:SI 0 "register_operand" "=r")
2941 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
2943 "andcc\t%1, 0xff, %0"
2944 [(set_attr "type" "compare")])
2946 (define_insn "*cmp_zero_extendqidi2"
2948 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
2951 "andcc\t%0, 0xff, %%g0"
2952 [(set_attr "type" "compare")])
2954 (define_insn "*cmp_zero_qi_sp64"
2956 (compare:CCX (match_operand:QI 0 "register_operand" "r")
2959 "andcc\t%0, 0xff, %%g0"
2960 [(set_attr "type" "compare")])
2962 (define_insn "*cmp_zero_extendqidi2_set"
2964 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
2966 (set (match_operand:DI 0 "register_operand" "=r")
2967 (zero_extend:DI (match_dup 1)))]
2969 "andcc\t%1, 0xff, %0"
2970 [(set_attr "type" "compare")])
2972 (define_insn "*cmp_zero_extendqidi2_andcc_set"
2974 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
2977 (set (match_operand:DI 0 "register_operand" "=r")
2978 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
2980 "andcc\t%1, 0xff, %0"
2981 [(set_attr "type" "compare")])
2983 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
2985 (define_insn "*cmp_siqi_trunc"
2987 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
2990 "andcc\t%0, 0xff, %%g0"
2991 [(set_attr "type" "compare")])
2993 (define_insn "*cmp_siqi_trunc_set"
2995 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
2997 (set (match_operand:QI 0 "register_operand" "=r")
2998 (subreg:QI (match_dup 1) 3))]
3000 "andcc\t%1, 0xff, %0"
3001 [(set_attr "type" "compare")])
3003 (define_insn "*cmp_diqi_trunc"
3005 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3008 "andcc\t%0, 0xff, %%g0"
3009 [(set_attr "type" "compare")])
3011 (define_insn "*cmp_diqi_trunc_set"
3013 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3015 (set (match_operand:QI 0 "register_operand" "=r")
3016 (subreg:QI (match_dup 1) 7))]
3018 "andcc\t%1, 0xff, %0"
3019 [(set_attr "type" "compare")])
3022 ;; Sign-extension instructions
3024 ;; These patterns originally accepted general_operands, however, slightly
3025 ;; better code is generated by only accepting register_operands, and then
3026 ;; letting combine generate the lds[hb] insns.
3028 (define_expand "extendhisi2"
3029 [(set (match_operand:SI 0 "register_operand" "")
3030 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3033 rtx temp = gen_reg_rtx (SImode);
3034 rtx shift_16 = GEN_INT (16);
3035 int op1_subbyte = 0;
3037 if (GET_CODE (operand1) == SUBREG)
3039 op1_subbyte = SUBREG_BYTE (operand1);
3040 op1_subbyte /= GET_MODE_SIZE (SImode);
3041 op1_subbyte *= GET_MODE_SIZE (SImode);
3042 operand1 = XEXP (operand1, 0);
3045 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3047 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3051 (define_insn "*sign_extendhisi2_insn"
3052 [(set (match_operand:SI 0 "register_operand" "=r")
3053 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3056 [(set_attr "type" "sload")
3057 (set_attr "us3load_type" "3cycle")])
3059 (define_expand "extendqihi2"
3060 [(set (match_operand:HI 0 "register_operand" "")
3061 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3064 rtx temp = gen_reg_rtx (SImode);
3065 rtx shift_24 = GEN_INT (24);
3066 int op1_subbyte = 0;
3067 int op0_subbyte = 0;
3069 if (GET_CODE (operand1) == SUBREG)
3071 op1_subbyte = SUBREG_BYTE (operand1);
3072 op1_subbyte /= GET_MODE_SIZE (SImode);
3073 op1_subbyte *= GET_MODE_SIZE (SImode);
3074 operand1 = XEXP (operand1, 0);
3076 if (GET_CODE (operand0) == SUBREG)
3078 op0_subbyte = SUBREG_BYTE (operand0);
3079 op0_subbyte /= GET_MODE_SIZE (SImode);
3080 op0_subbyte *= GET_MODE_SIZE (SImode);
3081 operand0 = XEXP (operand0, 0);
3083 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3085 if (GET_MODE (operand0) != SImode)
3086 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3087 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3091 (define_insn "*sign_extendqihi2_insn"
3092 [(set (match_operand:HI 0 "register_operand" "=r")
3093 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3096 [(set_attr "type" "sload")
3097 (set_attr "us3load_type" "3cycle")])
3099 (define_expand "extendqisi2"
3100 [(set (match_operand:SI 0 "register_operand" "")
3101 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3104 rtx temp = gen_reg_rtx (SImode);
3105 rtx shift_24 = GEN_INT (24);
3106 int op1_subbyte = 0;
3108 if (GET_CODE (operand1) == SUBREG)
3110 op1_subbyte = SUBREG_BYTE (operand1);
3111 op1_subbyte /= GET_MODE_SIZE (SImode);
3112 op1_subbyte *= GET_MODE_SIZE (SImode);
3113 operand1 = XEXP (operand1, 0);
3116 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3118 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3122 (define_insn "*sign_extendqisi2_insn"
3123 [(set (match_operand:SI 0 "register_operand" "=r")
3124 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3127 [(set_attr "type" "sload")
3128 (set_attr "us3load_type" "3cycle")])
3130 (define_expand "extendqidi2"
3131 [(set (match_operand:DI 0 "register_operand" "")
3132 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3135 rtx temp = gen_reg_rtx (DImode);
3136 rtx shift_56 = GEN_INT (56);
3137 int op1_subbyte = 0;
3139 if (GET_CODE (operand1) == SUBREG)
3141 op1_subbyte = SUBREG_BYTE (operand1);
3142 op1_subbyte /= GET_MODE_SIZE (DImode);
3143 op1_subbyte *= GET_MODE_SIZE (DImode);
3144 operand1 = XEXP (operand1, 0);
3147 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3149 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3153 (define_insn "*sign_extendqidi2_insn"
3154 [(set (match_operand:DI 0 "register_operand" "=r")
3155 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3158 [(set_attr "type" "sload")
3159 (set_attr "us3load_type" "3cycle")])
3161 (define_expand "extendhidi2"
3162 [(set (match_operand:DI 0 "register_operand" "")
3163 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3166 rtx temp = gen_reg_rtx (DImode);
3167 rtx shift_48 = GEN_INT (48);
3168 int op1_subbyte = 0;
3170 if (GET_CODE (operand1) == SUBREG)
3172 op1_subbyte = SUBREG_BYTE (operand1);
3173 op1_subbyte /= GET_MODE_SIZE (DImode);
3174 op1_subbyte *= GET_MODE_SIZE (DImode);
3175 operand1 = XEXP (operand1, 0);
3178 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3180 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3184 (define_insn "*sign_extendhidi2_insn"
3185 [(set (match_operand:DI 0 "register_operand" "=r")
3186 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3189 [(set_attr "type" "sload")
3190 (set_attr "us3load_type" "3cycle")])
3192 (define_expand "extendsidi2"
3193 [(set (match_operand:DI 0 "register_operand" "")
3194 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3198 (define_insn "*sign_extendsidi2_insn"
3199 [(set (match_operand:DI 0 "register_operand" "=r,r")
3200 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3205 [(set_attr "type" "shift,sload")
3206 (set_attr "us3load_type" "*,3cycle")])
3209 ;; Special pattern for optimizing bit-field compares. This is needed
3210 ;; because combine uses this as a canonical form.
3212 (define_insn "*cmp_zero_extract"
3215 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3216 (match_operand:SI 1 "small_int_operand" "I")
3217 (match_operand:SI 2 "small_int_operand" "I"))
3219 "INTVAL (operands[2]) > 19"
3221 int len = INTVAL (operands[1]);
3222 int pos = 32 - INTVAL (operands[2]) - len;
3223 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3224 operands[1] = GEN_INT (mask);
3225 return "andcc\t%0, %1, %%g0";
3227 [(set_attr "type" "compare")])
3229 (define_insn "*cmp_zero_extract_sp64"
3232 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3233 (match_operand:SI 1 "small_int_operand" "I")
3234 (match_operand:SI 2 "small_int_operand" "I"))
3236 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3238 int len = INTVAL (operands[1]);
3239 int pos = 64 - INTVAL (operands[2]) - len;
3240 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3241 operands[1] = GEN_INT (mask);
3242 return "andcc\t%0, %1, %%g0";
3244 [(set_attr "type" "compare")])
3247 ;; Conversions between float, double and long double.
3249 (define_insn "extendsfdf2"
3250 [(set (match_operand:DF 0 "register_operand" "=e")
3252 (match_operand:SF 1 "register_operand" "f")))]
3255 [(set_attr "type" "fp")
3256 (set_attr "fptype" "double")])
3258 (define_expand "extendsftf2"
3259 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3261 (match_operand:SF 1 "register_operand" "")))]
3262 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3263 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3265 (define_insn "*extendsftf2_hq"
3266 [(set (match_operand:TF 0 "register_operand" "=e")
3268 (match_operand:SF 1 "register_operand" "f")))]
3269 "TARGET_FPU && TARGET_HARD_QUAD"
3271 [(set_attr "type" "fp")])
3273 (define_expand "extenddftf2"
3274 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3276 (match_operand:DF 1 "register_operand" "")))]
3277 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3278 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3280 (define_insn "*extenddftf2_hq"
3281 [(set (match_operand:TF 0 "register_operand" "=e")
3283 (match_operand:DF 1 "register_operand" "e")))]
3284 "TARGET_FPU && TARGET_HARD_QUAD"
3286 [(set_attr "type" "fp")])
3288 (define_insn "truncdfsf2"
3289 [(set (match_operand:SF 0 "register_operand" "=f")
3291 (match_operand:DF 1 "register_operand" "e")))]
3294 [(set_attr "type" "fp")
3295 (set_attr "fptype" "double")])
3297 (define_expand "trunctfsf2"
3298 [(set (match_operand:SF 0 "register_operand" "")
3300 (match_operand:TF 1 "general_operand" "")))]
3301 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3302 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3304 (define_insn "*trunctfsf2_hq"
3305 [(set (match_operand:SF 0 "register_operand" "=f")
3307 (match_operand:TF 1 "register_operand" "e")))]
3308 "TARGET_FPU && TARGET_HARD_QUAD"
3310 [(set_attr "type" "fp")])
3312 (define_expand "trunctfdf2"
3313 [(set (match_operand:DF 0 "register_operand" "")
3315 (match_operand:TF 1 "general_operand" "")))]
3316 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3317 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3319 (define_insn "*trunctfdf2_hq"
3320 [(set (match_operand:DF 0 "register_operand" "=e")
3322 (match_operand:TF 1 "register_operand" "e")))]
3323 "TARGET_FPU && TARGET_HARD_QUAD"
3325 [(set_attr "type" "fp")])
3328 ;; Conversion between fixed point and floating point.
3330 (define_insn "floatsisf2"
3331 [(set (match_operand:SF 0 "register_operand" "=f")
3332 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3335 [(set_attr "type" "fp")
3336 (set_attr "fptype" "double")])
3338 (define_insn "floatsidf2"
3339 [(set (match_operand:DF 0 "register_operand" "=e")
3340 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3343 [(set_attr "type" "fp")
3344 (set_attr "fptype" "double")])
3346 (define_expand "floatsitf2"
3347 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3348 (float:TF (match_operand:SI 1 "register_operand" "")))]
3349 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3350 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3352 (define_insn "*floatsitf2_hq"
3353 [(set (match_operand:TF 0 "register_operand" "=e")
3354 (float:TF (match_operand:SI 1 "register_operand" "f")))]
3355 "TARGET_FPU && TARGET_HARD_QUAD"
3357 [(set_attr "type" "fp")])
3359 (define_expand "floatunssitf2"
3360 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3361 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3362 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3363 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3365 ;; Now the same for 64 bit sources.
3367 (define_insn "floatdisf2"
3368 [(set (match_operand:SF 0 "register_operand" "=f")
3369 (float:SF (match_operand:DI 1 "register_operand" "e")))]
3370 "TARGET_V9 && TARGET_FPU"
3372 [(set_attr "type" "fp")
3373 (set_attr "fptype" "double")])
3375 (define_expand "floatunsdisf2"
3376 [(use (match_operand:SF 0 "register_operand" ""))
3377 (use (match_operand:DI 1 "general_operand" ""))]
3378 "TARGET_ARCH64 && TARGET_FPU"
3379 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3381 (define_insn "floatdidf2"
3382 [(set (match_operand:DF 0 "register_operand" "=e")
3383 (float:DF (match_operand:DI 1 "register_operand" "e")))]
3384 "TARGET_V9 && TARGET_FPU"
3386 [(set_attr "type" "fp")
3387 (set_attr "fptype" "double")])
3389 (define_expand "floatunsdidf2"
3390 [(use (match_operand:DF 0 "register_operand" ""))
3391 (use (match_operand:DI 1 "general_operand" ""))]
3392 "TARGET_ARCH64 && TARGET_FPU"
3393 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3395 (define_expand "floatditf2"
3396 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3397 (float:TF (match_operand:DI 1 "register_operand" "")))]
3398 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3399 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3401 (define_insn "*floatditf2_hq"
3402 [(set (match_operand:TF 0 "register_operand" "=e")
3403 (float:TF (match_operand:DI 1 "register_operand" "e")))]
3404 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3406 [(set_attr "type" "fp")])
3408 (define_expand "floatunsditf2"
3409 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3410 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3411 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3412 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3414 ;; Convert a float to an actual integer.
3415 ;; Truncation is performed as part of the conversion.
3417 (define_insn "fix_truncsfsi2"
3418 [(set (match_operand:SI 0 "register_operand" "=f")
3419 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3422 [(set_attr "type" "fp")
3423 (set_attr "fptype" "double")])
3425 (define_insn "fix_truncdfsi2"
3426 [(set (match_operand:SI 0 "register_operand" "=f")
3427 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3430 [(set_attr "type" "fp")
3431 (set_attr "fptype" "double")])
3433 (define_expand "fix_trunctfsi2"
3434 [(set (match_operand:SI 0 "register_operand" "")
3435 (fix:SI (match_operand:TF 1 "general_operand" "")))]
3436 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3437 "emit_tfmode_cvt (FIX, operands); DONE;")
3439 (define_insn "*fix_trunctfsi2_hq"
3440 [(set (match_operand:SI 0 "register_operand" "=f")
3441 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
3442 "TARGET_FPU && TARGET_HARD_QUAD"
3444 [(set_attr "type" "fp")])
3446 (define_expand "fixuns_trunctfsi2"
3447 [(set (match_operand:SI 0 "register_operand" "")
3448 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
3449 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3450 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3452 ;; Now the same, for V9 targets
3454 (define_insn "fix_truncsfdi2"
3455 [(set (match_operand:DI 0 "register_operand" "=e")
3456 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3457 "TARGET_V9 && TARGET_FPU"
3459 [(set_attr "type" "fp")
3460 (set_attr "fptype" "double")])
3462 (define_expand "fixuns_truncsfdi2"
3463 [(use (match_operand:DI 0 "register_operand" ""))
3464 (use (match_operand:SF 1 "general_operand" ""))]
3465 "TARGET_ARCH64 && TARGET_FPU"
3466 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
3468 (define_insn "fix_truncdfdi2"
3469 [(set (match_operand:DI 0 "register_operand" "=e")
3470 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3471 "TARGET_V9 && TARGET_FPU"
3473 [(set_attr "type" "fp")
3474 (set_attr "fptype" "double")])
3476 (define_expand "fixuns_truncdfdi2"
3477 [(use (match_operand:DI 0 "register_operand" ""))
3478 (use (match_operand:DF 1 "general_operand" ""))]
3479 "TARGET_ARCH64 && TARGET_FPU"
3480 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
3482 (define_expand "fix_trunctfdi2"
3483 [(set (match_operand:DI 0 "register_operand" "")
3484 (fix:DI (match_operand:TF 1 "general_operand" "")))]
3485 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3486 "emit_tfmode_cvt (FIX, operands); DONE;")
3488 (define_insn "*fix_trunctfdi2_hq"
3489 [(set (match_operand:DI 0 "register_operand" "=e")
3490 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
3491 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3493 [(set_attr "type" "fp")])
3495 (define_expand "fixuns_trunctfdi2"
3496 [(set (match_operand:DI 0 "register_operand" "")
3497 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
3498 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3499 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3502 ;; Integer addition/subtraction instructions.
3504 (define_expand "adddi3"
3505 [(set (match_operand:DI 0 "register_operand" "")
3506 (plus:DI (match_operand:DI 1 "register_operand" "")
3507 (match_operand:DI 2 "arith_double_add_operand" "")))]
3510 if (! TARGET_ARCH64)
3512 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3513 gen_rtx_SET (VOIDmode, operands[0],
3514 gen_rtx_PLUS (DImode, operands[1],
3516 gen_rtx_CLOBBER (VOIDmode,
3517 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3522 (define_insn_and_split "*adddi3_insn_sp32"
3523 [(set (match_operand:DI 0 "register_operand" "=r")
3524 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3525 (match_operand:DI 2 "arith_double_operand" "rHI")))
3526 (clobber (reg:CC 100))]
3529 "&& reload_completed"
3530 [(parallel [(set (reg:CC_NOOV 100)
3531 (compare:CC_NOOV (plus:SI (match_dup 4)
3535 (plus:SI (match_dup 4) (match_dup 5)))])
3537 (plus:SI (plus:SI (match_dup 7)
3539 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3541 operands[3] = gen_lowpart (SImode, operands[0]);
3542 operands[4] = gen_lowpart (SImode, operands[1]);
3543 operands[5] = gen_lowpart (SImode, operands[2]);
3544 operands[6] = gen_highpart (SImode, operands[0]);
3545 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3546 #if HOST_BITS_PER_WIDE_INT == 32
3547 if (GET_CODE (operands[2]) == CONST_INT)
3549 if (INTVAL (operands[2]) < 0)
3550 operands[8] = constm1_rtx;
3552 operands[8] = const0_rtx;
3556 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3558 [(set_attr "length" "2")])
3560 ;; LTU here means "carry set"
3562 [(set (match_operand:SI 0 "register_operand" "=r")
3563 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3564 (match_operand:SI 2 "arith_operand" "rI"))
3565 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3568 [(set_attr "type" "ialuX")])
3570 (define_insn_and_split "*addx_extend_sp32"
3571 [(set (match_operand:DI 0 "register_operand" "=r")
3572 (zero_extend:DI (plus:SI (plus:SI
3573 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3574 (match_operand:SI 2 "arith_operand" "rI"))
3575 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3578 "&& reload_completed"
3579 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
3580 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
3581 (set (match_dup 4) (const_int 0))]
3582 "operands[3] = gen_lowpart (SImode, operands[0]);
3583 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
3584 [(set_attr "length" "2")])
3586 (define_insn "*addx_extend_sp64"
3587 [(set (match_operand:DI 0 "register_operand" "=r")
3588 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3589 (match_operand:SI 2 "arith_operand" "rI"))
3590 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3593 [(set_attr "type" "ialuX")])
3595 (define_insn_and_split "*adddi3_extend_sp32"
3596 [(set (match_operand:DI 0 "register_operand" "=r")
3597 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3598 (match_operand:DI 2 "register_operand" "r")))
3599 (clobber (reg:CC 100))]
3602 "&& reload_completed"
3603 [(parallel [(set (reg:CC_NOOV 100)
3604 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
3606 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
3608 (plus:SI (plus:SI (match_dup 4) (const_int 0))
3609 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3610 "operands[3] = gen_lowpart (SImode, operands[2]);
3611 operands[4] = gen_highpart (SImode, operands[2]);
3612 operands[5] = gen_lowpart (SImode, operands[0]);
3613 operands[6] = gen_highpart (SImode, operands[0]);"
3614 [(set_attr "length" "2")])
3616 (define_insn "*adddi3_sp64"
3617 [(set (match_operand:DI 0 "register_operand" "=r,r")
3618 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3619 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3625 (define_insn "addsi3"
3626 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3627 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
3628 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3633 fpadd32s\t%1, %2, %0"
3634 [(set_attr "type" "*,*,fga")
3635 (set_attr "fptype" "*,*,single")])
3637 (define_insn "*cmp_cc_plus"
3638 [(set (reg:CC_NOOV 100)
3639 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3640 (match_operand:SI 1 "arith_operand" "rI"))
3643 "addcc\t%0, %1, %%g0"
3644 [(set_attr "type" "compare")])
3646 (define_insn "*cmp_ccx_plus"
3647 [(set (reg:CCX_NOOV 100)
3648 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
3649 (match_operand:DI 1 "arith_operand" "rI"))
3652 "addcc\t%0, %1, %%g0"
3653 [(set_attr "type" "compare")])
3655 (define_insn "*cmp_cc_plus_set"
3656 [(set (reg:CC_NOOV 100)
3657 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3658 (match_operand:SI 2 "arith_operand" "rI"))
3660 (set (match_operand:SI 0 "register_operand" "=r")
3661 (plus:SI (match_dup 1) (match_dup 2)))]
3664 [(set_attr "type" "compare")])
3666 (define_insn "*cmp_ccx_plus_set"
3667 [(set (reg:CCX_NOOV 100)
3668 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
3669 (match_operand:DI 2 "arith_operand" "rI"))
3671 (set (match_operand:DI 0 "register_operand" "=r")
3672 (plus:DI (match_dup 1) (match_dup 2)))]
3675 [(set_attr "type" "compare")])
3677 (define_expand "subdi3"
3678 [(set (match_operand:DI 0 "register_operand" "")
3679 (minus:DI (match_operand:DI 1 "register_operand" "")
3680 (match_operand:DI 2 "arith_double_add_operand" "")))]
3683 if (! TARGET_ARCH64)
3685 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3686 gen_rtx_SET (VOIDmode, operands[0],
3687 gen_rtx_MINUS (DImode, operands[1],
3689 gen_rtx_CLOBBER (VOIDmode,
3690 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3695 (define_insn_and_split "*subdi3_insn_sp32"
3696 [(set (match_operand:DI 0 "register_operand" "=r")
3697 (minus:DI (match_operand:DI 1 "register_operand" "r")
3698 (match_operand:DI 2 "arith_double_operand" "rHI")))
3699 (clobber (reg:CC 100))]
3702 "&& reload_completed"
3703 [(parallel [(set (reg:CC_NOOV 100)
3704 (compare:CC_NOOV (minus:SI (match_dup 4)
3708 (minus:SI (match_dup 4) (match_dup 5)))])
3710 (minus:SI (minus:SI (match_dup 7)
3712 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3714 operands[3] = gen_lowpart (SImode, operands[0]);
3715 operands[4] = gen_lowpart (SImode, operands[1]);
3716 operands[5] = gen_lowpart (SImode, operands[2]);
3717 operands[6] = gen_highpart (SImode, operands[0]);
3718 operands[7] = gen_highpart (SImode, operands[1]);
3719 #if HOST_BITS_PER_WIDE_INT == 32
3720 if (GET_CODE (operands[2]) == CONST_INT)
3722 if (INTVAL (operands[2]) < 0)
3723 operands[8] = constm1_rtx;
3725 operands[8] = const0_rtx;
3729 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3731 [(set_attr "length" "2")])
3733 ;; LTU here means "carry set"
3735 [(set (match_operand:SI 0 "register_operand" "=r")
3736 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3737 (match_operand:SI 2 "arith_operand" "rI"))
3738 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3741 [(set_attr "type" "ialuX")])
3743 (define_insn "*subx_extend_sp64"
3744 [(set (match_operand:DI 0 "register_operand" "=r")
3745 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3746 (match_operand:SI 2 "arith_operand" "rI"))
3747 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3750 [(set_attr "type" "ialuX")])
3752 (define_insn_and_split "*subx_extend"
3753 [(set (match_operand:DI 0 "register_operand" "=r")
3754 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3755 (match_operand:SI 2 "arith_operand" "rI"))
3756 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3759 "&& reload_completed"
3760 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
3761 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
3762 (set (match_dup 4) (const_int 0))]
3763 "operands[3] = gen_lowpart (SImode, operands[0]);
3764 operands[4] = gen_highpart (SImode, operands[0]);"
3765 [(set_attr "length" "2")])
3767 (define_insn_and_split "*subdi3_extend_sp32"
3768 [(set (match_operand:DI 0 "register_operand" "=r")
3769 (minus:DI (match_operand:DI 1 "register_operand" "r")
3770 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
3771 (clobber (reg:CC 100))]
3774 "&& reload_completed"
3775 [(parallel [(set (reg:CC_NOOV 100)
3776 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
3778 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
3780 (minus:SI (minus:SI (match_dup 4) (const_int 0))
3781 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3782 "operands[3] = gen_lowpart (SImode, operands[1]);
3783 operands[4] = gen_highpart (SImode, operands[1]);
3784 operands[5] = gen_lowpart (SImode, operands[0]);
3785 operands[6] = gen_highpart (SImode, operands[0]);"
3786 [(set_attr "length" "2")])
3788 (define_insn "*subdi3_sp64"
3789 [(set (match_operand:DI 0 "register_operand" "=r,r")
3790 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
3791 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3797 (define_insn "subsi3"
3798 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3799 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
3800 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3805 fpsub32s\t%1, %2, %0"
3806 [(set_attr "type" "*,*,fga")
3807 (set_attr "fptype" "*,*,single")])
3809 (define_insn "*cmp_minus_cc"
3810 [(set (reg:CC_NOOV 100)
3811 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
3812 (match_operand:SI 1 "arith_operand" "rI"))
3815 "subcc\t%r0, %1, %%g0"
3816 [(set_attr "type" "compare")])
3818 (define_insn "*cmp_minus_ccx"
3819 [(set (reg:CCX_NOOV 100)
3820 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
3821 (match_operand:DI 1 "arith_operand" "rI"))
3824 "subcc\t%0, %1, %%g0"
3825 [(set_attr "type" "compare")])
3827 (define_insn "cmp_minus_cc_set"
3828 [(set (reg:CC_NOOV 100)
3829 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3830 (match_operand:SI 2 "arith_operand" "rI"))
3832 (set (match_operand:SI 0 "register_operand" "=r")
3833 (minus:SI (match_dup 1) (match_dup 2)))]
3835 "subcc\t%r1, %2, %0"
3836 [(set_attr "type" "compare")])
3838 (define_insn "*cmp_minus_ccx_set"
3839 [(set (reg:CCX_NOOV 100)
3840 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
3841 (match_operand:DI 2 "arith_operand" "rI"))
3843 (set (match_operand:DI 0 "register_operand" "=r")
3844 (minus:DI (match_dup 1) (match_dup 2)))]
3847 [(set_attr "type" "compare")])
3850 ;; Integer multiply/divide instructions.
3852 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
3853 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
3855 (define_insn "mulsi3"
3856 [(set (match_operand:SI 0 "register_operand" "=r")
3857 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3858 (match_operand:SI 2 "arith_operand" "rI")))]
3861 [(set_attr "type" "imul")])
3863 (define_expand "muldi3"
3864 [(set (match_operand:DI 0 "register_operand" "")
3865 (mult:DI (match_operand:DI 1 "arith_operand" "")
3866 (match_operand:DI 2 "arith_operand" "")))]
3867 "TARGET_ARCH64 || TARGET_V8PLUS"
3871 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
3876 (define_insn "*muldi3_sp64"
3877 [(set (match_operand:DI 0 "register_operand" "=r")
3878 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
3879 (match_operand:DI 2 "arith_operand" "rI")))]
3882 [(set_attr "type" "imul")])
3884 ;; V8plus wide multiply.
3886 (define_insn "muldi3_v8plus"
3887 [(set (match_operand:DI 0 "register_operand" "=r,h")
3888 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
3889 (match_operand:DI 2 "arith_operand" "rI,rI")))
3890 (clobber (match_scratch:SI 3 "=&h,X"))
3891 (clobber (match_scratch:SI 4 "=&h,X"))]
3894 if (sparc_check_64 (operands[1], insn) <= 0)
3895 output_asm_insn ("srl\t%L1, 0, %L1", operands);
3896 if (which_alternative == 1)
3897 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
3898 if (GET_CODE (operands[2]) == CONST_INT)
3900 if (which_alternative == 1)
3901 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
3903 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";
3905 else if (rtx_equal_p (operands[1], operands[2]))
3907 if (which_alternative == 1)
3908 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
3910 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";
3912 if (sparc_check_64 (operands[2], insn) <= 0)
3913 output_asm_insn ("srl\t%L2, 0, %L2", operands);
3914 if (which_alternative == 1)
3915 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";
3917 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";
3919 [(set_attr "type" "multi")
3920 (set_attr "length" "9,8")])
3922 (define_insn "*cmp_mul_set"
3924 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3925 (match_operand:SI 2 "arith_operand" "rI"))
3927 (set (match_operand:SI 0 "register_operand" "=r")
3928 (mult:SI (match_dup 1) (match_dup 2)))]
3929 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
3930 "smulcc\t%1, %2, %0"
3931 [(set_attr "type" "imul")])
3933 (define_expand "mulsidi3"
3934 [(set (match_operand:DI 0 "register_operand" "")
3935 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
3936 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
3939 if (CONSTANT_P (operands[2]))
3942 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
3944 else if (TARGET_ARCH32)
3945 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
3948 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
3954 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
3959 ;; V9 puts the 64-bit product in a 64-bit register. Only out or global
3960 ;; registers can hold 64-bit values in the V8plus environment.
3962 (define_insn "mulsidi3_v8plus"
3963 [(set (match_operand:DI 0 "register_operand" "=h,r")
3964 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
3965 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
3966 (clobber (match_scratch:SI 3 "=X,&h"))]
3969 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
3970 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
3971 [(set_attr "type" "multi")
3972 (set_attr "length" "2,3")])
3975 (define_insn "const_mulsidi3_v8plus"
3976 [(set (match_operand:DI 0 "register_operand" "=h,r")
3977 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
3978 (match_operand:DI 2 "small_int_operand" "I,I")))
3979 (clobber (match_scratch:SI 3 "=X,&h"))]
3982 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
3983 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
3984 [(set_attr "type" "multi")
3985 (set_attr "length" "2,3")])
3988 (define_insn "*mulsidi3_sp32"
3989 [(set (match_operand:DI 0 "register_operand" "=r")
3990 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3991 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
3994 return TARGET_SPARCLET
3995 ? "smuld\t%1, %2, %L0"
3996 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
3999 (if_then_else (eq_attr "isa" "sparclet")
4000 (const_string "imul") (const_string "multi")))
4001 (set (attr "length")
4002 (if_then_else (eq_attr "isa" "sparclet")
4003 (const_int 1) (const_int 2)))])
4005 (define_insn "*mulsidi3_sp64"
4006 [(set (match_operand:DI 0 "register_operand" "=r")
4007 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4008 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4009 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4011 [(set_attr "type" "imul")])
4013 ;; Extra pattern, because sign_extend of a constant isn't valid.
4016 (define_insn "const_mulsidi3_sp32"
4017 [(set (match_operand:DI 0 "register_operand" "=r")
4018 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4019 (match_operand:DI 2 "small_int_operand" "I")))]
4022 return TARGET_SPARCLET
4023 ? "smuld\t%1, %2, %L0"
4024 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4027 (if_then_else (eq_attr "isa" "sparclet")
4028 (const_string "imul") (const_string "multi")))
4029 (set (attr "length")
4030 (if_then_else (eq_attr "isa" "sparclet")
4031 (const_int 1) (const_int 2)))])
4033 (define_insn "const_mulsidi3_sp64"
4034 [(set (match_operand:DI 0 "register_operand" "=r")
4035 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4036 (match_operand:DI 2 "small_int_operand" "I")))]
4037 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4039 [(set_attr "type" "imul")])
4041 (define_expand "smulsi3_highpart"
4042 [(set (match_operand:SI 0 "register_operand" "")
4044 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4045 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4047 "TARGET_HARD_MUL && TARGET_ARCH32"
4049 if (CONSTANT_P (operands[2]))
4053 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4059 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4064 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4065 operands[2], GEN_INT (32)));
4071 (define_insn "smulsi3_highpart_v8plus"
4072 [(set (match_operand:SI 0 "register_operand" "=h,r")
4074 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4075 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4076 (match_operand:SI 3 "small_int_operand" "I,I"))))
4077 (clobber (match_scratch:SI 4 "=X,&h"))]
4080 smul\t%1, %2, %0\;srlx\t%0, %3, %0
4081 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4082 [(set_attr "type" "multi")
4083 (set_attr "length" "2")])
4085 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4088 [(set (match_operand:SI 0 "register_operand" "=h,r")
4091 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4092 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4093 (match_operand:SI 3 "small_int_operand" "I,I"))
4095 (clobber (match_scratch:SI 4 "=X,&h"))]
4098 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4099 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4100 [(set_attr "type" "multi")
4101 (set_attr "length" "2")])
4104 (define_insn "const_smulsi3_highpart_v8plus"
4105 [(set (match_operand:SI 0 "register_operand" "=h,r")
4107 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4108 (match_operand:DI 2 "small_int_operand" "I,I"))
4109 (match_operand:SI 3 "small_int_operand" "I,I"))))
4110 (clobber (match_scratch:SI 4 "=X,&h"))]
4113 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4114 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4115 [(set_attr "type" "multi")
4116 (set_attr "length" "2")])
4119 (define_insn "*smulsi3_highpart_sp32"
4120 [(set (match_operand:SI 0 "register_operand" "=r")
4122 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4123 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4126 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4127 [(set_attr "type" "multi")
4128 (set_attr "length" "2")])
4131 (define_insn "const_smulsi3_highpart"
4132 [(set (match_operand:SI 0 "register_operand" "=r")
4134 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4135 (match_operand:DI 2 "small_int_operand" "i"))
4138 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4139 [(set_attr "type" "multi")
4140 (set_attr "length" "2")])
4142 (define_expand "umulsidi3"
4143 [(set (match_operand:DI 0 "register_operand" "")
4144 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4145 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4148 if (CONSTANT_P (operands[2]))
4151 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4153 else if (TARGET_ARCH32)
4154 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4157 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4163 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4169 (define_insn "umulsidi3_v8plus"
4170 [(set (match_operand:DI 0 "register_operand" "=h,r")
4171 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4172 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4173 (clobber (match_scratch:SI 3 "=X,&h"))]
4176 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4177 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4178 [(set_attr "type" "multi")
4179 (set_attr "length" "2,3")])
4182 (define_insn "*umulsidi3_sp32"
4183 [(set (match_operand:DI 0 "register_operand" "=r")
4184 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4185 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4188 return TARGET_SPARCLET
4189 ? "umuld\t%1, %2, %L0"
4190 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4193 (if_then_else (eq_attr "isa" "sparclet")
4194 (const_string "imul") (const_string "multi")))
4195 (set (attr "length")
4196 (if_then_else (eq_attr "isa" "sparclet")
4197 (const_int 1) (const_int 2)))])
4199 (define_insn "*umulsidi3_sp64"
4200 [(set (match_operand:DI 0 "register_operand" "=r")
4201 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4202 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4203 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4205 [(set_attr "type" "imul")])
4207 ;; Extra pattern, because sign_extend of a constant isn't valid.
4210 (define_insn "const_umulsidi3_sp32"
4211 [(set (match_operand:DI 0 "register_operand" "=r")
4212 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4213 (match_operand:DI 2 "uns_small_int_operand" "")))]
4216 return TARGET_SPARCLET
4217 ? "umuld\t%1, %s2, %L0"
4218 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4221 (if_then_else (eq_attr "isa" "sparclet")
4222 (const_string "imul") (const_string "multi")))
4223 (set (attr "length")
4224 (if_then_else (eq_attr "isa" "sparclet")
4225 (const_int 1) (const_int 2)))])
4227 (define_insn "const_umulsidi3_sp64"
4228 [(set (match_operand:DI 0 "register_operand" "=r")
4229 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4230 (match_operand:DI 2 "uns_small_int_operand" "")))]
4231 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4233 [(set_attr "type" "imul")])
4236 (define_insn "const_umulsidi3_v8plus"
4237 [(set (match_operand:DI 0 "register_operand" "=h,r")
4238 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4239 (match_operand:DI 2 "uns_small_int_operand" "")))
4240 (clobber (match_scratch:SI 3 "=X,h"))]
4243 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4244 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4245 [(set_attr "type" "multi")
4246 (set_attr "length" "2,3")])
4248 (define_expand "umulsi3_highpart"
4249 [(set (match_operand:SI 0 "register_operand" "")
4251 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4252 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4254 "TARGET_HARD_MUL && TARGET_ARCH32"
4256 if (CONSTANT_P (operands[2]))
4260 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4266 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4271 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4272 operands[2], GEN_INT (32)));
4278 (define_insn "umulsi3_highpart_v8plus"
4279 [(set (match_operand:SI 0 "register_operand" "=h,r")
4281 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4282 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4283 (match_operand:SI 3 "small_int_operand" "I,I"))))
4284 (clobber (match_scratch:SI 4 "=X,h"))]
4287 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4288 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4289 [(set_attr "type" "multi")
4290 (set_attr "length" "2")])
4293 (define_insn "const_umulsi3_highpart_v8plus"
4294 [(set (match_operand:SI 0 "register_operand" "=h,r")
4296 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4297 (match_operand:DI 2 "uns_small_int_operand" ""))
4298 (match_operand:SI 3 "small_int_operand" "I,I"))))
4299 (clobber (match_scratch:SI 4 "=X,h"))]
4302 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4303 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4304 [(set_attr "type" "multi")
4305 (set_attr "length" "2")])
4308 (define_insn "*umulsi3_highpart_sp32"
4309 [(set (match_operand:SI 0 "register_operand" "=r")
4311 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4312 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4315 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4316 [(set_attr "type" "multi")
4317 (set_attr "length" "2")])
4320 (define_insn "const_umulsi3_highpart"
4321 [(set (match_operand:SI 0 "register_operand" "=r")
4323 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4324 (match_operand:DI 2 "uns_small_int_operand" ""))
4327 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4328 [(set_attr "type" "multi")
4329 (set_attr "length" "2")])
4331 (define_expand "divsi3"
4332 [(parallel [(set (match_operand:SI 0 "register_operand" "")
4333 (div:SI (match_operand:SI 1 "register_operand" "")
4334 (match_operand:SI 2 "input_operand" "")))
4335 (clobber (match_scratch:SI 3 ""))])]
4336 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4340 operands[3] = gen_reg_rtx(SImode);
4341 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4342 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4348 ;; The V8 architecture specifies that there must be at least 3 instructions
4349 ;; between a write to the Y register and a use of it for correct results.
4350 ;; We try to fill one of them with a simple constant or a memory load.
4352 (define_insn "divsi3_sp32"
4353 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4354 (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4355 (match_operand:SI 2 "input_operand" "rI,K,m")))
4356 (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4357 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4359 output_asm_insn ("sra\t%1, 31, %3", operands);
4360 output_asm_insn ("wr\t%3, 0, %%y", operands);
4362 switch (which_alternative)
4366 return "sdiv\t%1, %2, %0";
4368 return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4371 return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4373 return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4376 return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4378 return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4383 [(set_attr "type" "multi")
4384 (set (attr "length")
4385 (if_then_else (eq_attr "isa" "v9")
4386 (const_int 4) (const_int 6)))])
4388 (define_insn "divsi3_sp64"
4389 [(set (match_operand:SI 0 "register_operand" "=r")
4390 (div:SI (match_operand:SI 1 "register_operand" "r")
4391 (match_operand:SI 2 "input_operand" "rI")))
4392 (use (match_operand:SI 3 "register_operand" "r"))]
4393 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4394 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4395 [(set_attr "type" "multi")
4396 (set_attr "length" "2")])
4398 (define_insn "divdi3"
4399 [(set (match_operand:DI 0 "register_operand" "=r")
4400 (div:DI (match_operand:DI 1 "register_operand" "r")
4401 (match_operand:DI 2 "arith_operand" "rI")))]
4404 [(set_attr "type" "idiv")])
4406 (define_insn "*cmp_sdiv_cc_set"
4408 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4409 (match_operand:SI 2 "arith_operand" "rI"))
4411 (set (match_operand:SI 0 "register_operand" "=r")
4412 (div:SI (match_dup 1) (match_dup 2)))
4413 (clobber (match_scratch:SI 3 "=&r"))]
4414 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4416 output_asm_insn ("sra\t%1, 31, %3", operands);
4417 output_asm_insn ("wr\t%3, 0, %%y", operands);
4420 return "sdivcc\t%1, %2, %0";
4422 return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4424 [(set_attr "type" "multi")
4425 (set (attr "length")
4426 (if_then_else (eq_attr "isa" "v9")
4427 (const_int 3) (const_int 6)))])
4430 (define_expand "udivsi3"
4431 [(set (match_operand:SI 0 "register_operand" "")
4432 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4433 (match_operand:SI 2 "input_operand" "")))]
4434 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4437 ;; The V8 architecture specifies that there must be at least 3 instructions
4438 ;; between a write to the Y register and a use of it for correct results.
4439 ;; We try to fill one of them with a simple constant or a memory load.
4441 (define_insn "udivsi3_sp32"
4442 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
4443 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
4444 (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
4445 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4447 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4449 switch (which_alternative)
4453 return "udiv\t%1, %2, %0";
4455 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
4458 return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
4460 return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4463 return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
4465 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4468 return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
4470 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
4475 [(set_attr "type" "multi")
4476 (set (attr "length")
4477 (if_then_else (eq_attr "isa" "v9")
4478 (const_int 3) (const_int 5)))])
4480 (define_insn "udivsi3_sp64"
4481 [(set (match_operand:SI 0 "register_operand" "=r")
4482 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
4483 (match_operand:SI 2 "input_operand" "rI")))]
4484 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4485 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
4486 [(set_attr "type" "multi")
4487 (set_attr "length" "2")])
4489 (define_insn "udivdi3"
4490 [(set (match_operand:DI 0 "register_operand" "=r")
4491 (udiv:DI (match_operand:DI 1 "register_operand" "r")
4492 (match_operand:DI 2 "arith_operand" "rI")))]
4495 [(set_attr "type" "idiv")])
4497 (define_insn "*cmp_udiv_cc_set"
4499 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
4500 (match_operand:SI 2 "arith_operand" "rI"))
4502 (set (match_operand:SI 0 "register_operand" "=r")
4503 (udiv:SI (match_dup 1) (match_dup 2)))]
4504 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4506 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4509 return "udivcc\t%1, %2, %0";
4511 return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
4513 [(set_attr "type" "multi")
4514 (set (attr "length")
4515 (if_then_else (eq_attr "isa" "v9")
4516 (const_int 2) (const_int 5)))])
4518 ; sparclet multiply/accumulate insns
4520 (define_insn "*smacsi"
4521 [(set (match_operand:SI 0 "register_operand" "=r")
4522 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
4523 (match_operand:SI 2 "arith_operand" "rI"))
4524 (match_operand:SI 3 "register_operand" "0")))]
4527 [(set_attr "type" "imul")])
4529 (define_insn "*smacdi"
4530 [(set (match_operand:DI 0 "register_operand" "=r")
4531 (plus:DI (mult:DI (sign_extend:DI
4532 (match_operand:SI 1 "register_operand" "%r"))
4534 (match_operand:SI 2 "register_operand" "r")))
4535 (match_operand:DI 3 "register_operand" "0")))]
4537 "smacd\t%1, %2, %L0"
4538 [(set_attr "type" "imul")])
4540 (define_insn "*umacdi"
4541 [(set (match_operand:DI 0 "register_operand" "=r")
4542 (plus:DI (mult:DI (zero_extend:DI
4543 (match_operand:SI 1 "register_operand" "%r"))
4545 (match_operand:SI 2 "register_operand" "r")))
4546 (match_operand:DI 3 "register_operand" "0")))]
4548 "umacd\t%1, %2, %L0"
4549 [(set_attr "type" "imul")])
4552 ;; Boolean instructions.
4554 ;; We define DImode `and' so with DImode `not' we can get
4555 ;; DImode `andn'. Other combinations are possible.
4557 (define_expand "and<V64I:mode>3"
4558 [(set (match_operand:V64I 0 "register_operand" "")
4559 (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
4560 (match_operand:V64I 2 "arith_double_operand" "")))]
4564 (define_insn "*and<V64I:mode>3_sp32"
4565 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4566 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4567 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4572 [(set_attr "type" "*,fga")
4573 (set_attr "length" "2,*")
4574 (set_attr "fptype" "*,double")])
4576 (define_insn "*and<V64I:mode>3_sp64"
4577 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4578 (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4579 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4584 [(set_attr "type" "*,fga")
4585 (set_attr "fptype" "*,double")])
4587 (define_insn "and<V32I:mode>3"
4588 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4589 (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4590 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4595 [(set_attr "type" "*,fga")
4596 (set_attr "fptype" "*,single")])
4599 [(set (match_operand:SI 0 "register_operand" "")
4600 (and:SI (match_operand:SI 1 "register_operand" "")
4601 (match_operand:SI 2 "const_compl_high_operand" "")))
4602 (clobber (match_operand:SI 3 "register_operand" ""))]
4604 [(set (match_dup 3) (match_dup 4))
4605 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
4607 operands[4] = GEN_INT (~INTVAL (operands[2]));
4610 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
4611 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4612 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4613 (match_operand:V64I 2 "register_operand" "r,b")))]
4617 fandnot1\t%1, %2, %0"
4618 "&& reload_completed
4619 && ((GET_CODE (operands[0]) == REG
4620 && REGNO (operands[0]) < 32)
4621 || (GET_CODE (operands[0]) == SUBREG
4622 && GET_CODE (SUBREG_REG (operands[0])) == REG
4623 && REGNO (SUBREG_REG (operands[0])) < 32))"
4624 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
4625 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
4626 "operands[3] = gen_highpart (SImode, operands[0]);
4627 operands[4] = gen_highpart (SImode, operands[1]);
4628 operands[5] = gen_highpart (SImode, operands[2]);
4629 operands[6] = gen_lowpart (SImode, operands[0]);
4630 operands[7] = gen_lowpart (SImode, operands[1]);
4631 operands[8] = gen_lowpart (SImode, operands[2]);"
4632 [(set_attr "type" "*,fga")
4633 (set_attr "length" "2,*")
4634 (set_attr "fptype" "*,double")])
4636 (define_insn "*and_not_<V64I:mode>_sp64"
4637 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4638 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4639 (match_operand:V64I 2 "register_operand" "r,b")))]
4643 fandnot1\t%1, %2, %0"
4644 [(set_attr "type" "*,fga")
4645 (set_attr "fptype" "*,double")])
4647 (define_insn "*and_not_<V32I:mode>"
4648 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4649 (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
4650 (match_operand:V32I 2 "register_operand" "r,d")))]
4654 fandnot1s\t%1, %2, %0"
4655 [(set_attr "type" "*,fga")
4656 (set_attr "fptype" "*,single")])
4658 (define_expand "ior<V64I:mode>3"
4659 [(set (match_operand:V64I 0 "register_operand" "")
4660 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
4661 (match_operand:V64I 2 "arith_double_operand" "")))]
4665 (define_insn "*ior<V64I:mode>3_sp32"
4666 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4667 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4668 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4673 [(set_attr "type" "*,fga")
4674 (set_attr "length" "2,*")
4675 (set_attr "fptype" "*,double")])
4677 (define_insn "*ior<V64I:mode>3_sp64"
4678 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4679 (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4680 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4685 [(set_attr "type" "*,fga")
4686 (set_attr "fptype" "*,double")])
4688 (define_insn "ior<V32I:mode>3"
4689 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4690 (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4691 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4696 [(set_attr "type" "*,fga")
4697 (set_attr "fptype" "*,single")])
4700 [(set (match_operand:SI 0 "register_operand" "")
4701 (ior:SI (match_operand:SI 1 "register_operand" "")
4702 (match_operand:SI 2 "const_compl_high_operand" "")))
4703 (clobber (match_operand:SI 3 "register_operand" ""))]
4705 [(set (match_dup 3) (match_dup 4))
4706 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4708 operands[4] = GEN_INT (~INTVAL (operands[2]));
4711 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
4712 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4713 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4714 (match_operand:V64I 2 "register_operand" "r,b")))]
4718 fornot1\t%1, %2, %0"
4719 "&& reload_completed
4720 && ((GET_CODE (operands[0]) == REG
4721 && REGNO (operands[0]) < 32)
4722 || (GET_CODE (operands[0]) == SUBREG
4723 && GET_CODE (SUBREG_REG (operands[0])) == REG
4724 && REGNO (SUBREG_REG (operands[0])) < 32))"
4725 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
4726 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
4727 "operands[3] = gen_highpart (SImode, operands[0]);
4728 operands[4] = gen_highpart (SImode, operands[1]);
4729 operands[5] = gen_highpart (SImode, operands[2]);
4730 operands[6] = gen_lowpart (SImode, operands[0]);
4731 operands[7] = gen_lowpart (SImode, operands[1]);
4732 operands[8] = gen_lowpart (SImode, operands[2]);"
4733 [(set_attr "type" "*,fga")
4734 (set_attr "length" "2,*")
4735 (set_attr "fptype" "*,double")])
4737 (define_insn "*or_not_<V64I:mode>_sp64"
4738 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4739 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4740 (match_operand:V64I 2 "register_operand" "r,b")))]
4744 fornot1\t%1, %2, %0"
4745 [(set_attr "type" "*,fga")
4746 (set_attr "fptype" "*,double")])
4748 (define_insn "*or_not_<V32I:mode>"
4749 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4750 (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
4751 (match_operand:V32I 2 "register_operand" "r,d")))]
4755 fornot1s\t%1, %2, %0"
4756 [(set_attr "type" "*,fga")
4757 (set_attr "fptype" "*,single")])
4759 (define_expand "xor<V64I:mode>3"
4760 [(set (match_operand:V64I 0 "register_operand" "")
4761 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
4762 (match_operand:V64I 2 "arith_double_operand" "")))]
4766 (define_insn "*xor<V64I:mode>3_sp32"
4767 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4768 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4769 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4774 [(set_attr "type" "*,fga")
4775 (set_attr "length" "2,*")
4776 (set_attr "fptype" "*,double")])
4778 (define_insn "*xor<V64I:mode>3_sp64"
4779 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4780 (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
4781 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4786 [(set_attr "type" "*,fga")
4787 (set_attr "fptype" "*,double")])
4789 (define_insn "xor<V32I:mode>3"
4790 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4791 (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
4792 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4797 [(set_attr "type" "*,fga")
4798 (set_attr "fptype" "*,single")])
4801 [(set (match_operand:SI 0 "register_operand" "")
4802 (xor:SI (match_operand:SI 1 "register_operand" "")
4803 (match_operand:SI 2 "const_compl_high_operand" "")))
4804 (clobber (match_operand:SI 3 "register_operand" ""))]
4806 [(set (match_dup 3) (match_dup 4))
4807 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4809 operands[4] = GEN_INT (~INTVAL (operands[2]));
4813 [(set (match_operand:SI 0 "register_operand" "")
4814 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
4815 (match_operand:SI 2 "const_compl_high_operand" ""))))
4816 (clobber (match_operand:SI 3 "register_operand" ""))]
4818 [(set (match_dup 3) (match_dup 4))
4819 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
4821 operands[4] = GEN_INT (~INTVAL (operands[2]));
4824 ;; Split DImode logical operations requiring two instructions.
4826 [(set (match_operand:V64I 0 "register_operand" "")
4827 (match_operator:V64I 1 "cc_arith_operator" ; AND, IOR, XOR
4828 [(match_operand:V64I 2 "register_operand" "")
4829 (match_operand:V64I 3 "arith_double_operand" "")]))]
4832 && ((GET_CODE (operands[0]) == REG
4833 && REGNO (operands[0]) < 32)
4834 || (GET_CODE (operands[0]) == SUBREG
4835 && GET_CODE (SUBREG_REG (operands[0])) == REG
4836 && REGNO (SUBREG_REG (operands[0])) < 32))"
4837 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
4838 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
4840 operands[4] = gen_highpart (SImode, operands[0]);
4841 operands[5] = gen_lowpart (SImode, operands[0]);
4842 operands[6] = gen_highpart (SImode, operands[2]);
4843 operands[7] = gen_lowpart (SImode, operands[2]);
4844 #if HOST_BITS_PER_WIDE_INT == 32
4845 if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
4847 if (INTVAL (operands[3]) < 0)
4848 operands[8] = constm1_rtx;
4850 operands[8] = const0_rtx;
4854 operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
4855 operands[9] = gen_lowpart (SImode, operands[3]);
4858 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
4859 ;; Combine now canonicalizes to the rightmost expression.
4860 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
4861 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4862 (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
4863 (match_operand:V64I 2 "register_operand" "r,b"))))]
4868 "&& reload_completed
4869 && ((GET_CODE (operands[0]) == REG
4870 && REGNO (operands[0]) < 32)
4871 || (GET_CODE (operands[0]) == SUBREG
4872 && GET_CODE (SUBREG_REG (operands[0])) == REG
4873 && REGNO (SUBREG_REG (operands[0])) < 32))"
4874 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
4875 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
4876 "operands[3] = gen_highpart (SImode, operands[0]);
4877 operands[4] = gen_highpart (SImode, operands[1]);
4878 operands[5] = gen_highpart (SImode, operands[2]);
4879 operands[6] = gen_lowpart (SImode, operands[0]);
4880 operands[7] = gen_lowpart (SImode, operands[1]);
4881 operands[8] = gen_lowpart (SImode, operands[2]);"
4882 [(set_attr "type" "*,fga")
4883 (set_attr "length" "2,*")
4884 (set_attr "fptype" "*,double")])
4886 (define_insn "*xor_not_<V64I:mode>_sp64"
4887 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4888 (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
4889 (match_operand:V64I 2 "arith_operand" "rI,b"))))]
4894 [(set_attr "type" "*,fga")
4895 (set_attr "fptype" "*,double")])
4897 (define_insn "*xor_not_<V32I:mode>"
4898 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4899 (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
4900 (match_operand:V32I 2 "arith_operand" "rI,d"))))]
4905 [(set_attr "type" "*,fga")
4906 (set_attr "fptype" "*,single")])
4908 ;; These correspond to the above in the case where we also (or only)
4909 ;; want to set the condition code.
4911 (define_insn "*cmp_cc_arith_op"
4914 (match_operator:SI 2 "cc_arith_operator"
4915 [(match_operand:SI 0 "arith_operand" "%r")
4916 (match_operand:SI 1 "arith_operand" "rI")])
4919 "%A2cc\t%0, %1, %%g0"
4920 [(set_attr "type" "compare")])
4922 (define_insn "*cmp_ccx_arith_op"
4925 (match_operator:DI 2 "cc_arith_operator"
4926 [(match_operand:DI 0 "arith_operand" "%r")
4927 (match_operand:DI 1 "arith_operand" "rI")])
4930 "%A2cc\t%0, %1, %%g0"
4931 [(set_attr "type" "compare")])
4933 (define_insn "*cmp_cc_arith_op_set"
4936 (match_operator:SI 3 "cc_arith_operator"
4937 [(match_operand:SI 1 "arith_operand" "%r")
4938 (match_operand:SI 2 "arith_operand" "rI")])
4940 (set (match_operand:SI 0 "register_operand" "=r")
4941 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
4942 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
4944 [(set_attr "type" "compare")])
4946 (define_insn "*cmp_ccx_arith_op_set"
4949 (match_operator:DI 3 "cc_arith_operator"
4950 [(match_operand:DI 1 "arith_operand" "%r")
4951 (match_operand:DI 2 "arith_operand" "rI")])
4953 (set (match_operand:DI 0 "register_operand" "=r")
4954 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
4955 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
4957 [(set_attr "type" "compare")])
4959 (define_insn "*cmp_cc_xor_not"
4962 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
4963 (match_operand:SI 1 "arith_operand" "rI")))
4966 "xnorcc\t%r0, %1, %%g0"
4967 [(set_attr "type" "compare")])
4969 (define_insn "*cmp_ccx_xor_not"
4972 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
4973 (match_operand:DI 1 "arith_operand" "rI")))
4976 "xnorcc\t%r0, %1, %%g0"
4977 [(set_attr "type" "compare")])
4979 (define_insn "*cmp_cc_xor_not_set"
4982 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4983 (match_operand:SI 2 "arith_operand" "rI")))
4985 (set (match_operand:SI 0 "register_operand" "=r")
4986 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
4988 "xnorcc\t%r1, %2, %0"
4989 [(set_attr "type" "compare")])
4991 (define_insn "*cmp_ccx_xor_not_set"
4994 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
4995 (match_operand:DI 2 "arith_operand" "rI")))
4997 (set (match_operand:DI 0 "register_operand" "=r")
4998 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5000 "xnorcc\t%r1, %2, %0"
5001 [(set_attr "type" "compare")])
5003 (define_insn "*cmp_cc_arith_op_not"
5006 (match_operator:SI 2 "cc_arith_not_operator"
5007 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5008 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5011 "%B2cc\t%r1, %0, %%g0"
5012 [(set_attr "type" "compare")])
5014 (define_insn "*cmp_ccx_arith_op_not"
5017 (match_operator:DI 2 "cc_arith_not_operator"
5018 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5019 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5022 "%B2cc\t%r1, %0, %%g0"
5023 [(set_attr "type" "compare")])
5025 (define_insn "*cmp_cc_arith_op_not_set"
5028 (match_operator:SI 3 "cc_arith_not_operator"
5029 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5030 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5032 (set (match_operand:SI 0 "register_operand" "=r")
5033 (match_operator:SI 4 "cc_arith_not_operator"
5034 [(not:SI (match_dup 1)) (match_dup 2)]))]
5035 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5036 "%B3cc\t%r2, %1, %0"
5037 [(set_attr "type" "compare")])
5039 (define_insn "*cmp_ccx_arith_op_not_set"
5042 (match_operator:DI 3 "cc_arith_not_operator"
5043 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5044 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5046 (set (match_operand:DI 0 "register_operand" "=r")
5047 (match_operator:DI 4 "cc_arith_not_operator"
5048 [(not:DI (match_dup 1)) (match_dup 2)]))]
5049 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5050 "%B3cc\t%r2, %1, %0"
5051 [(set_attr "type" "compare")])
5053 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5054 ;; does not know how to make it work for constants.
5056 (define_expand "negdi2"
5057 [(set (match_operand:DI 0 "register_operand" "=r")
5058 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5061 if (! TARGET_ARCH64)
5063 emit_insn (gen_rtx_PARALLEL
5066 gen_rtx_SET (VOIDmode, operand0,
5067 gen_rtx_NEG (DImode, operand1)),
5068 gen_rtx_CLOBBER (VOIDmode,
5069 gen_rtx_REG (CCmode,
5075 (define_insn_and_split "*negdi2_sp32"
5076 [(set (match_operand:DI 0 "register_operand" "=r")
5077 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5078 (clobber (reg:CC 100))]
5081 "&& reload_completed"
5082 [(parallel [(set (reg:CC_NOOV 100)
5083 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5085 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5086 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5087 (ltu:SI (reg:CC 100) (const_int 0))))]
5088 "operands[2] = gen_highpart (SImode, operands[0]);
5089 operands[3] = gen_highpart (SImode, operands[1]);
5090 operands[4] = gen_lowpart (SImode, operands[0]);
5091 operands[5] = gen_lowpart (SImode, operands[1]);"
5092 [(set_attr "length" "2")])
5094 (define_insn "*negdi2_sp64"
5095 [(set (match_operand:DI 0 "register_operand" "=r")
5096 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5098 "sub\t%%g0, %1, %0")
5100 (define_insn "negsi2"
5101 [(set (match_operand:SI 0 "register_operand" "=r")
5102 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5104 "sub\t%%g0, %1, %0")
5106 (define_insn "*cmp_cc_neg"
5107 [(set (reg:CC_NOOV 100)
5108 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5111 "subcc\t%%g0, %0, %%g0"
5112 [(set_attr "type" "compare")])
5114 (define_insn "*cmp_ccx_neg"
5115 [(set (reg:CCX_NOOV 100)
5116 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5119 "subcc\t%%g0, %0, %%g0"
5120 [(set_attr "type" "compare")])
5122 (define_insn "*cmp_cc_set_neg"
5123 [(set (reg:CC_NOOV 100)
5124 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5126 (set (match_operand:SI 0 "register_operand" "=r")
5127 (neg:SI (match_dup 1)))]
5129 "subcc\t%%g0, %1, %0"
5130 [(set_attr "type" "compare")])
5132 (define_insn "*cmp_ccx_set_neg"
5133 [(set (reg:CCX_NOOV 100)
5134 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5136 (set (match_operand:DI 0 "register_operand" "=r")
5137 (neg:DI (match_dup 1)))]
5139 "subcc\t%%g0, %1, %0"
5140 [(set_attr "type" "compare")])
5142 ;; We cannot use the "not" pseudo insn because the Sun assembler
5143 ;; does not know how to make it work for constants.
5144 (define_expand "one_cmpl<V64I:mode>2"
5145 [(set (match_operand:V64I 0 "register_operand" "")
5146 (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5150 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5151 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5152 (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5157 "&& reload_completed
5158 && ((GET_CODE (operands[0]) == REG
5159 && REGNO (operands[0]) < 32)
5160 || (GET_CODE (operands[0]) == SUBREG
5161 && GET_CODE (SUBREG_REG (operands[0])) == REG
5162 && REGNO (SUBREG_REG (operands[0])) < 32))"
5163 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5164 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5165 "operands[2] = gen_highpart (SImode, operands[0]);
5166 operands[3] = gen_highpart (SImode, operands[1]);
5167 operands[4] = gen_lowpart (SImode, operands[0]);
5168 operands[5] = gen_lowpart (SImode, operands[1]);"
5169 [(set_attr "type" "*,fga")
5170 (set_attr "length" "2,*")
5171 (set_attr "fptype" "*,double")])
5173 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5174 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5175 (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5180 [(set_attr "type" "*,fga")
5181 (set_attr "fptype" "*,double")])
5183 (define_insn "one_cmpl<V32I:mode>2"
5184 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5185 (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5190 [(set_attr "type" "*,fga")
5191 (set_attr "fptype" "*,single")])
5193 (define_insn "*cmp_cc_not"
5195 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5198 "xnorcc\t%%g0, %0, %%g0"
5199 [(set_attr "type" "compare")])
5201 (define_insn "*cmp_ccx_not"
5203 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5206 "xnorcc\t%%g0, %0, %%g0"
5207 [(set_attr "type" "compare")])
5209 (define_insn "*cmp_cc_set_not"
5211 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5213 (set (match_operand:SI 0 "register_operand" "=r")
5214 (not:SI (match_dup 1)))]
5216 "xnorcc\t%%g0, %1, %0"
5217 [(set_attr "type" "compare")])
5219 (define_insn "*cmp_ccx_set_not"
5221 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5223 (set (match_operand:DI 0 "register_operand" "=r")
5224 (not:DI (match_dup 1)))]
5226 "xnorcc\t%%g0, %1, %0"
5227 [(set_attr "type" "compare")])
5229 (define_insn "*cmp_cc_set"
5230 [(set (match_operand:SI 0 "register_operand" "=r")
5231 (match_operand:SI 1 "register_operand" "r"))
5233 (compare:CC (match_dup 1)
5237 [(set_attr "type" "compare")])
5239 (define_insn "*cmp_ccx_set64"
5240 [(set (match_operand:DI 0 "register_operand" "=r")
5241 (match_operand:DI 1 "register_operand" "r"))
5243 (compare:CCX (match_dup 1)
5247 [(set_attr "type" "compare")])
5250 ;; Floating point arithmetic instructions.
5252 (define_expand "addtf3"
5253 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5254 (plus:TF (match_operand:TF 1 "general_operand" "")
5255 (match_operand:TF 2 "general_operand" "")))]
5256 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5257 "emit_tfmode_binop (PLUS, operands); DONE;")
5259 (define_insn "*addtf3_hq"
5260 [(set (match_operand:TF 0 "register_operand" "=e")
5261 (plus:TF (match_operand:TF 1 "register_operand" "e")
5262 (match_operand:TF 2 "register_operand" "e")))]
5263 "TARGET_FPU && TARGET_HARD_QUAD"
5265 [(set_attr "type" "fp")])
5267 (define_insn "adddf3"
5268 [(set (match_operand:DF 0 "register_operand" "=e")
5269 (plus:DF (match_operand:DF 1 "register_operand" "e")
5270 (match_operand:DF 2 "register_operand" "e")))]
5273 [(set_attr "type" "fp")
5274 (set_attr "fptype" "double")])
5276 (define_insn "addsf3"
5277 [(set (match_operand:SF 0 "register_operand" "=f")
5278 (plus:SF (match_operand:SF 1 "register_operand" "f")
5279 (match_operand:SF 2 "register_operand" "f")))]
5282 [(set_attr "type" "fp")])
5284 (define_expand "subtf3"
5285 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5286 (minus:TF (match_operand:TF 1 "general_operand" "")
5287 (match_operand:TF 2 "general_operand" "")))]
5288 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5289 "emit_tfmode_binop (MINUS, operands); DONE;")
5291 (define_insn "*subtf3_hq"
5292 [(set (match_operand:TF 0 "register_operand" "=e")
5293 (minus:TF (match_operand:TF 1 "register_operand" "e")
5294 (match_operand:TF 2 "register_operand" "e")))]
5295 "TARGET_FPU && TARGET_HARD_QUAD"
5297 [(set_attr "type" "fp")])
5299 (define_insn "subdf3"
5300 [(set (match_operand:DF 0 "register_operand" "=e")
5301 (minus:DF (match_operand:DF 1 "register_operand" "e")
5302 (match_operand:DF 2 "register_operand" "e")))]
5305 [(set_attr "type" "fp")
5306 (set_attr "fptype" "double")])
5308 (define_insn "subsf3"
5309 [(set (match_operand:SF 0 "register_operand" "=f")
5310 (minus:SF (match_operand:SF 1 "register_operand" "f")
5311 (match_operand:SF 2 "register_operand" "f")))]
5314 [(set_attr "type" "fp")])
5316 (define_expand "multf3"
5317 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5318 (mult:TF (match_operand:TF 1 "general_operand" "")
5319 (match_operand:TF 2 "general_operand" "")))]
5320 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5321 "emit_tfmode_binop (MULT, operands); DONE;")
5323 (define_insn "*multf3_hq"
5324 [(set (match_operand:TF 0 "register_operand" "=e")
5325 (mult:TF (match_operand:TF 1 "register_operand" "e")
5326 (match_operand:TF 2 "register_operand" "e")))]
5327 "TARGET_FPU && TARGET_HARD_QUAD"
5329 [(set_attr "type" "fpmul")])
5331 (define_insn "muldf3"
5332 [(set (match_operand:DF 0 "register_operand" "=e")
5333 (mult:DF (match_operand:DF 1 "register_operand" "e")
5334 (match_operand:DF 2 "register_operand" "e")))]
5337 [(set_attr "type" "fpmul")
5338 (set_attr "fptype" "double")])
5340 (define_insn "mulsf3"
5341 [(set (match_operand:SF 0 "register_operand" "=f")
5342 (mult:SF (match_operand:SF 1 "register_operand" "f")
5343 (match_operand:SF 2 "register_operand" "f")))]
5346 [(set_attr "type" "fpmul")])
5348 (define_insn "*muldf3_extend"
5349 [(set (match_operand:DF 0 "register_operand" "=e")
5350 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5351 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5352 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
5353 "fsmuld\t%1, %2, %0"
5354 [(set_attr "type" "fpmul")
5355 (set_attr "fptype" "double")])
5357 (define_insn "*multf3_extend"
5358 [(set (match_operand:TF 0 "register_operand" "=e")
5359 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5360 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5361 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5362 "fdmulq\t%1, %2, %0"
5363 [(set_attr "type" "fpmul")])
5365 (define_expand "divtf3"
5366 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5367 (div:TF (match_operand:TF 1 "general_operand" "")
5368 (match_operand:TF 2 "general_operand" "")))]
5369 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5370 "emit_tfmode_binop (DIV, operands); DONE;")
5372 ;; don't have timing for quad-prec. divide.
5373 (define_insn "*divtf3_hq"
5374 [(set (match_operand:TF 0 "register_operand" "=e")
5375 (div:TF (match_operand:TF 1 "register_operand" "e")
5376 (match_operand:TF 2 "register_operand" "e")))]
5377 "TARGET_FPU && TARGET_HARD_QUAD"
5379 [(set_attr "type" "fpdivd")])
5381 (define_insn "divdf3"
5382 [(set (match_operand:DF 0 "register_operand" "=e")
5383 (div:DF (match_operand:DF 1 "register_operand" "e")
5384 (match_operand:DF 2 "register_operand" "e")))]
5387 [(set_attr "type" "fpdivd")
5388 (set_attr "fptype" "double")])
5390 (define_insn "divsf3"
5391 [(set (match_operand:SF 0 "register_operand" "=f")
5392 (div:SF (match_operand:SF 1 "register_operand" "f")
5393 (match_operand:SF 2 "register_operand" "f")))]
5396 [(set_attr "type" "fpdivs")])
5398 (define_expand "negtf2"
5399 [(set (match_operand:TF 0 "register_operand" "=e,e")
5400 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5404 (define_insn_and_split "*negtf2_notv9"
5405 [(set (match_operand:TF 0 "register_operand" "=e,e")
5406 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5407 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5413 "&& reload_completed
5414 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5415 [(set (match_dup 2) (neg:SF (match_dup 3)))
5416 (set (match_dup 4) (match_dup 5))
5417 (set (match_dup 6) (match_dup 7))]
5418 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5419 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5420 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5421 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5422 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5423 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5424 [(set_attr "type" "fpmove,*")
5425 (set_attr "length" "*,2")])
5427 (define_insn_and_split "*negtf2_v9"
5428 [(set (match_operand:TF 0 "register_operand" "=e,e")
5429 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5430 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5431 "TARGET_FPU && TARGET_V9"
5435 "&& reload_completed
5436 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5437 [(set (match_dup 2) (neg:DF (match_dup 3)))
5438 (set (match_dup 4) (match_dup 5))]
5439 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5440 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5441 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5442 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5443 [(set_attr "type" "fpmove,*")
5444 (set_attr "length" "*,2")
5445 (set_attr "fptype" "double")])
5447 (define_expand "negdf2"
5448 [(set (match_operand:DF 0 "register_operand" "")
5449 (neg:DF (match_operand:DF 1 "register_operand" "")))]
5453 (define_insn_and_split "*negdf2_notv9"
5454 [(set (match_operand:DF 0 "register_operand" "=e,e")
5455 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
5456 "TARGET_FPU && ! TARGET_V9"
5460 "&& reload_completed
5461 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5462 [(set (match_dup 2) (neg:SF (match_dup 3)))
5463 (set (match_dup 4) (match_dup 5))]
5464 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5465 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5466 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5467 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5468 [(set_attr "type" "fpmove,*")
5469 (set_attr "length" "*,2")])
5471 (define_insn "*negdf2_v9"
5472 [(set (match_operand:DF 0 "register_operand" "=e")
5473 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5474 "TARGET_FPU && TARGET_V9"
5476 [(set_attr "type" "fpmove")
5477 (set_attr "fptype" "double")])
5479 (define_insn "negsf2"
5480 [(set (match_operand:SF 0 "register_operand" "=f")
5481 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
5484 [(set_attr "type" "fpmove")])
5486 (define_expand "abstf2"
5487 [(set (match_operand:TF 0 "register_operand" "")
5488 (abs:TF (match_operand:TF 1 "register_operand" "")))]
5492 (define_insn_and_split "*abstf2_notv9"
5493 [(set (match_operand:TF 0 "register_operand" "=e,e")
5494 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5495 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5496 "TARGET_FPU && ! TARGET_V9"
5500 "&& reload_completed
5501 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5502 [(set (match_dup 2) (abs:SF (match_dup 3)))
5503 (set (match_dup 4) (match_dup 5))
5504 (set (match_dup 6) (match_dup 7))]
5505 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5506 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5507 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5508 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5509 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5510 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5511 [(set_attr "type" "fpmove,*")
5512 (set_attr "length" "*,2")])
5514 (define_insn "*abstf2_hq_v9"
5515 [(set (match_operand:TF 0 "register_operand" "=e,e")
5516 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5517 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
5521 [(set_attr "type" "fpmove")
5522 (set_attr "fptype" "double,*")])
5524 (define_insn_and_split "*abstf2_v9"
5525 [(set (match_operand:TF 0 "register_operand" "=e,e")
5526 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5527 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
5531 "&& reload_completed
5532 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5533 [(set (match_dup 2) (abs:DF (match_dup 3)))
5534 (set (match_dup 4) (match_dup 5))]
5535 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5536 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5537 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5538 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5539 [(set_attr "type" "fpmove,*")
5540 (set_attr "length" "*,2")
5541 (set_attr "fptype" "double,*")])
5543 (define_expand "absdf2"
5544 [(set (match_operand:DF 0 "register_operand" "")
5545 (abs:DF (match_operand:DF 1 "register_operand" "")))]
5549 (define_insn_and_split "*absdf2_notv9"
5550 [(set (match_operand:DF 0 "register_operand" "=e,e")
5551 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
5552 "TARGET_FPU && ! TARGET_V9"
5556 "&& reload_completed
5557 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5558 [(set (match_dup 2) (abs:SF (match_dup 3)))
5559 (set (match_dup 4) (match_dup 5))]
5560 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5561 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5562 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5563 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5564 [(set_attr "type" "fpmove,*")
5565 (set_attr "length" "*,2")])
5567 (define_insn "*absdf2_v9"
5568 [(set (match_operand:DF 0 "register_operand" "=e")
5569 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5570 "TARGET_FPU && TARGET_V9"
5572 [(set_attr "type" "fpmove")
5573 (set_attr "fptype" "double")])
5575 (define_insn "abssf2"
5576 [(set (match_operand:SF 0 "register_operand" "=f")
5577 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
5580 [(set_attr "type" "fpmove")])
5582 (define_expand "sqrttf2"
5583 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5584 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
5585 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5586 "emit_tfmode_unop (SQRT, operands); DONE;")
5588 (define_insn "*sqrttf2_hq"
5589 [(set (match_operand:TF 0 "register_operand" "=e")
5590 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
5591 "TARGET_FPU && TARGET_HARD_QUAD"
5593 [(set_attr "type" "fpsqrtd")])
5595 (define_insn "sqrtdf2"
5596 [(set (match_operand:DF 0 "register_operand" "=e")
5597 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5600 [(set_attr "type" "fpsqrtd")
5601 (set_attr "fptype" "double")])
5603 (define_insn "sqrtsf2"
5604 [(set (match_operand:SF 0 "register_operand" "=f")
5605 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
5608 [(set_attr "type" "fpsqrts")])
5611 ;; Arithmetic shift instructions.
5613 (define_insn "ashlsi3"
5614 [(set (match_operand:SI 0 "register_operand" "=r")
5615 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5616 (match_operand:SI 2 "arith_operand" "rI")))]
5619 if (GET_CODE (operands[2]) == CONST_INT)
5620 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5621 return "sll\t%1, %2, %0";
5624 (if_then_else (match_operand 2 "const_one_operand" "")
5625 (const_string "ialu") (const_string "shift")))])
5627 (define_expand "ashldi3"
5628 [(set (match_operand:DI 0 "register_operand" "=r")
5629 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5630 (match_operand:SI 2 "arith_operand" "rI")))]
5631 "TARGET_ARCH64 || TARGET_V8PLUS"
5633 if (! TARGET_ARCH64)
5635 if (GET_CODE (operands[2]) == CONST_INT)
5637 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
5642 (define_insn "*ashldi3_sp64"
5643 [(set (match_operand:DI 0 "register_operand" "=r")
5644 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5645 (match_operand:SI 2 "arith_operand" "rI")))]
5648 if (GET_CODE (operands[2]) == CONST_INT)
5649 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5650 return "sllx\t%1, %2, %0";
5653 (if_then_else (match_operand 2 "const_one_operand" "")
5654 (const_string "ialu") (const_string "shift")))])
5657 (define_insn "ashldi3_v8plus"
5658 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5659 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5660 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5661 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5663 "* return output_v8plus_shift (operands, insn, \"sllx\");"
5664 [(set_attr "type" "multi")
5665 (set_attr "length" "5,5,6")])
5667 ;; Optimize (1LL<<x)-1
5668 ;; XXX this also needs to be fixed to handle equal subregs
5669 ;; XXX first before we could re-enable it.
5671 ; [(set (match_operand:DI 0 "register_operand" "=h")
5672 ; (plus:DI (ashift:DI (const_int 1)
5673 ; (match_operand:SI 1 "arith_operand" "rI"))
5675 ; "0 && TARGET_V8PLUS"
5677 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
5678 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5679 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5681 ; [(set_attr "type" "multi")
5682 ; (set_attr "length" "4")])
5684 (define_insn "*cmp_cc_ashift_1"
5685 [(set (reg:CC_NOOV 100)
5686 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
5690 "addcc\t%0, %0, %%g0"
5691 [(set_attr "type" "compare")])
5693 (define_insn "*cmp_cc_set_ashift_1"
5694 [(set (reg:CC_NOOV 100)
5695 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
5698 (set (match_operand:SI 0 "register_operand" "=r")
5699 (ashift:SI (match_dup 1) (const_int 1)))]
5702 [(set_attr "type" "compare")])
5704 (define_insn "ashrsi3"
5705 [(set (match_operand:SI 0 "register_operand" "=r")
5706 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5707 (match_operand:SI 2 "arith_operand" "rI")))]
5710 if (GET_CODE (operands[2]) == CONST_INT)
5711 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5712 return "sra\t%1, %2, %0";
5714 [(set_attr "type" "shift")])
5716 (define_insn "*ashrsi3_extend"
5717 [(set (match_operand:DI 0 "register_operand" "=r")
5718 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5719 (match_operand:SI 2 "arith_operand" "r"))))]
5722 [(set_attr "type" "shift")])
5724 ;; This handles the case as above, but with constant shift instead of
5725 ;; register. Combiner "simplifies" it for us a little bit though.
5726 (define_insn "*ashrsi3_extend2"
5727 [(set (match_operand:DI 0 "register_operand" "=r")
5728 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5730 (match_operand:SI 2 "small_int_operand" "I")))]
5731 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
5733 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5734 return "sra\t%1, %2, %0";
5736 [(set_attr "type" "shift")])
5738 (define_expand "ashrdi3"
5739 [(set (match_operand:DI 0 "register_operand" "=r")
5740 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5741 (match_operand:SI 2 "arith_operand" "rI")))]
5742 "TARGET_ARCH64 || TARGET_V8PLUS"
5744 if (! TARGET_ARCH64)
5746 if (GET_CODE (operands[2]) == CONST_INT)
5747 FAIL; /* prefer generic code in this case */
5748 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
5753 (define_insn "*ashrdi3_sp64"
5754 [(set (match_operand:DI 0 "register_operand" "=r")
5755 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5756 (match_operand:SI 2 "arith_operand" "rI")))]
5760 if (GET_CODE (operands[2]) == CONST_INT)
5761 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5762 return "srax\t%1, %2, %0";
5764 [(set_attr "type" "shift")])
5767 (define_insn "ashrdi3_v8plus"
5768 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5769 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5770 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5771 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5773 "* return output_v8plus_shift (operands, insn, \"srax\");"
5774 [(set_attr "type" "multi")
5775 (set_attr "length" "5,5,6")])
5777 (define_insn "lshrsi3"
5778 [(set (match_operand:SI 0 "register_operand" "=r")
5779 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5780 (match_operand:SI 2 "arith_operand" "rI")))]
5783 if (GET_CODE (operands[2]) == CONST_INT)
5784 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5785 return "srl\t%1, %2, %0";
5787 [(set_attr "type" "shift")])
5789 ;; This handles the case where
5790 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
5791 ;; but combiner "simplifies" it for us.
5792 (define_insn "*lshrsi3_extend"
5793 [(set (match_operand:DI 0 "register_operand" "=r")
5794 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5795 (match_operand:SI 2 "arith_operand" "r")) 0)
5796 (match_operand 3 "const_int_operand" "")))]
5797 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
5799 [(set_attr "type" "shift")])
5801 ;; This handles the case where
5802 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
5803 ;; but combiner "simplifies" it for us.
5804 (define_insn "*lshrsi3_extend2"
5805 [(set (match_operand:DI 0 "register_operand" "=r")
5806 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5807 (match_operand 2 "small_int_operand" "I")
5809 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5811 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
5812 return "srl\t%1, %2, %0";
5814 [(set_attr "type" "shift")])
5816 (define_expand "lshrdi3"
5817 [(set (match_operand:DI 0 "register_operand" "=r")
5818 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5819 (match_operand:SI 2 "arith_operand" "rI")))]
5820 "TARGET_ARCH64 || TARGET_V8PLUS"
5822 if (! TARGET_ARCH64)
5824 if (GET_CODE (operands[2]) == CONST_INT)
5826 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
5831 (define_insn "*lshrdi3_sp64"
5832 [(set (match_operand:DI 0 "register_operand" "=r")
5833 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5834 (match_operand:SI 2 "arith_operand" "rI")))]
5837 if (GET_CODE (operands[2]) == CONST_INT)
5838 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5839 return "srlx\t%1, %2, %0";
5841 [(set_attr "type" "shift")])
5844 (define_insn "lshrdi3_v8plus"
5845 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5846 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5847 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5848 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5850 "* return output_v8plus_shift (operands, insn, \"srlx\");"
5851 [(set_attr "type" "multi")
5852 (set_attr "length" "5,5,6")])
5855 [(set (match_operand:SI 0 "register_operand" "=r")
5856 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5858 (match_operand:SI 2 "small_int_operand" "I")))]
5859 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5861 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
5862 return "srax\t%1, %2, %0";
5864 [(set_attr "type" "shift")])
5867 [(set (match_operand:SI 0 "register_operand" "=r")
5868 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5870 (match_operand:SI 2 "small_int_operand" "I")))]
5871 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5873 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
5874 return "srlx\t%1, %2, %0";
5876 [(set_attr "type" "shift")])
5879 [(set (match_operand:SI 0 "register_operand" "=r")
5880 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5881 (match_operand:SI 2 "small_int_operand" "I")) 4)
5882 (match_operand:SI 3 "small_int_operand" "I")))]
5884 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
5885 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
5886 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
5888 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
5890 return "srax\t%1, %2, %0";
5892 [(set_attr "type" "shift")])
5895 [(set (match_operand:SI 0 "register_operand" "=r")
5896 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5897 (match_operand:SI 2 "small_int_operand" "I")) 4)
5898 (match_operand:SI 3 "small_int_operand" "I")))]
5900 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
5901 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
5902 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
5904 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
5906 return "srlx\t%1, %2, %0";
5908 [(set_attr "type" "shift")])
5911 ;; Unconditional and other jump instructions.
5914 [(set (pc) (label_ref (match_operand 0 "" "")))]
5916 "* return output_ubranch (operands[0], 0, insn);"
5917 [(set_attr "type" "uncond_branch")])
5919 (define_expand "tablejump"
5920 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
5921 (use (label_ref (match_operand 1 "" "")))])]
5924 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
5926 /* In pic mode, our address differences are against the base of the
5927 table. Add that base value back in; CSE ought to be able to combine
5928 the two address loads. */
5932 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
5934 if (CASE_VECTOR_MODE != Pmode)
5935 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
5936 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
5937 operands[0] = memory_address (Pmode, tmp);
5941 (define_insn "*tablejump_sp32"
5942 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
5943 (use (label_ref (match_operand 1 "" "")))]
5946 [(set_attr "type" "uncond_branch")])
5948 (define_insn "*tablejump_sp64"
5949 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
5950 (use (label_ref (match_operand 1 "" "")))]
5953 [(set_attr "type" "uncond_branch")])
5956 ;; Jump to subroutine instructions.
5958 (define_expand "call"
5959 ;; Note that this expression is not used for generating RTL.
5960 ;; All the RTL is generated explicitly below.
5961 [(call (match_operand 0 "call_operand" "")
5962 (match_operand 3 "" "i"))]
5963 ;; operands[2] is next_arg_register
5964 ;; operands[3] is struct_value_size_rtx.
5969 gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
5971 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
5973 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
5975 /* This is really a PIC sequence. We want to represent
5976 it as a funny jump so its delay slots can be filled.
5978 ??? But if this really *is* a CALL, will not it clobber the
5979 call-clobbered registers? We lose this if it is a JUMP_INSN.
5980 Why cannot we have delay slots filled if it were a CALL? */
5982 /* We accept negative sizes for untyped calls. */
5983 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
5988 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
5990 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
5996 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
5997 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6001 fn_rtx = operands[0];
6003 /* We accept negative sizes for untyped calls. */
6004 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6005 sparc_emit_call_insn
6008 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6010 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6013 sparc_emit_call_insn
6016 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6017 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6025 ;; We can't use the same pattern for these two insns, because then registers
6026 ;; in the address may not be properly reloaded.
6028 (define_insn "*call_address_sp32"
6029 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6030 (match_operand 1 "" ""))
6031 (clobber (reg:SI 15))]
6032 ;;- Do not use operand 1 for most machines.
6035 [(set_attr "type" "call")])
6037 (define_insn "*call_symbolic_sp32"
6038 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6039 (match_operand 1 "" ""))
6040 (clobber (reg:SI 15))]
6041 ;;- Do not use operand 1 for most machines.
6044 [(set_attr "type" "call")])
6046 (define_insn "*call_address_sp64"
6047 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6048 (match_operand 1 "" ""))
6049 (clobber (reg:DI 15))]
6050 ;;- Do not use operand 1 for most machines.
6053 [(set_attr "type" "call")])
6055 (define_insn "*call_symbolic_sp64"
6056 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6057 (match_operand 1 "" ""))
6058 (clobber (reg:DI 15))]
6059 ;;- Do not use operand 1 for most machines.
6062 [(set_attr "type" "call")])
6064 ;; This is a call that wants a structure value.
6065 ;; There is no such critter for v9 (??? we may need one anyway).
6066 (define_insn "*call_address_struct_value_sp32"
6067 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6068 (match_operand 1 "" ""))
6069 (match_operand 2 "immediate_operand" "")
6070 (clobber (reg:SI 15))]
6071 ;;- Do not use operand 1 for most machines.
6072 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6074 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6075 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6077 [(set_attr "type" "call_no_delay_slot")
6078 (set_attr "length" "3")])
6080 ;; This is a call that wants a structure value.
6081 ;; There is no such critter for v9 (??? we may need one anyway).
6082 (define_insn "*call_symbolic_struct_value_sp32"
6083 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6084 (match_operand 1 "" ""))
6085 (match_operand 2 "immediate_operand" "")
6086 (clobber (reg:SI 15))]
6087 ;;- Do not use operand 1 for most machines.
6088 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6090 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6091 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6093 [(set_attr "type" "call_no_delay_slot")
6094 (set_attr "length" "3")])
6096 ;; This is a call that may want a structure value. This is used for
6098 (define_insn "*call_address_untyped_struct_value_sp32"
6099 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6100 (match_operand 1 "" ""))
6101 (match_operand 2 "immediate_operand" "")
6102 (clobber (reg:SI 15))]
6103 ;;- Do not use operand 1 for most machines.
6104 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6105 "call\t%a0, %1\n\t nop\n\tnop"
6106 [(set_attr "type" "call_no_delay_slot")
6107 (set_attr "length" "3")])
6109 ;; This is a call that may want a structure value. This is used for
6111 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6112 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6113 (match_operand 1 "" ""))
6114 (match_operand 2 "immediate_operand" "")
6115 (clobber (reg:SI 15))]
6116 ;;- Do not use operand 1 for most machines.
6117 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6118 "call\t%a0, %1\n\t nop\n\tnop"
6119 [(set_attr "type" "call_no_delay_slot")
6120 (set_attr "length" "3")])
6122 (define_expand "call_value"
6123 ;; Note that this expression is not used for generating RTL.
6124 ;; All the RTL is generated explicitly below.
6125 [(set (match_operand 0 "register_operand" "=rf")
6126 (call (match_operand 1 "" "")
6127 (match_operand 4 "" "")))]
6128 ;; operand 2 is stack_size_rtx
6129 ;; operand 3 is next_arg_register
6135 gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6137 fn_rtx = operands[1];
6140 gen_rtx_SET (VOIDmode, operands[0],
6141 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6142 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6144 sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6149 (define_insn "*call_value_address_sp32"
6150 [(set (match_operand 0 "" "=rf")
6151 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6152 (match_operand 2 "" "")))
6153 (clobber (reg:SI 15))]
6154 ;;- Do not use operand 2 for most machines.
6157 [(set_attr "type" "call")])
6159 (define_insn "*call_value_symbolic_sp32"
6160 [(set (match_operand 0 "" "=rf")
6161 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6162 (match_operand 2 "" "")))
6163 (clobber (reg:SI 15))]
6164 ;;- Do not use operand 2 for most machines.
6167 [(set_attr "type" "call")])
6169 (define_insn "*call_value_address_sp64"
6170 [(set (match_operand 0 "" "")
6171 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6172 (match_operand 2 "" "")))
6173 (clobber (reg:DI 15))]
6174 ;;- Do not use operand 2 for most machines.
6177 [(set_attr "type" "call")])
6179 (define_insn "*call_value_symbolic_sp64"
6180 [(set (match_operand 0 "" "")
6181 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6182 (match_operand 2 "" "")))
6183 (clobber (reg:DI 15))]
6184 ;;- Do not use operand 2 for most machines.
6187 [(set_attr "type" "call")])
6189 (define_expand "untyped_call"
6190 [(parallel [(call (match_operand 0 "" "")
6192 (match_operand:BLK 1 "memory_operand" "")
6193 (match_operand 2 "" "")])]
6196 rtx valreg1 = gen_rtx_REG (DImode, 8);
6197 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6198 rtx result = operands[1];
6200 /* Pass constm1 to indicate that it may expect a structure value, but
6201 we don't know what size it is. */
6202 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6204 /* Save the function value registers. */
6205 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6206 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6209 /* The optimizer does not know that the call sets the function value
6210 registers we stored in the result block. We avoid problems by
6211 claiming that all hard registers are used and clobbered at this
6213 emit_insn (gen_blockage ());
6218 ;; Tail call instructions.
6220 (define_expand "sibcall"
6221 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6226 (define_insn "*sibcall_symbolic_sp32"
6227 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6228 (match_operand 1 "" ""))
6231 "* return output_sibcall(insn, operands[0]);"
6232 [(set_attr "type" "sibcall")])
6234 (define_insn "*sibcall_symbolic_sp64"
6235 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6236 (match_operand 1 "" ""))
6239 "* return output_sibcall(insn, operands[0]);"
6240 [(set_attr "type" "sibcall")])
6242 (define_expand "sibcall_value"
6243 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6244 (call (match_operand 1 "" "") (const_int 0)))
6249 (define_insn "*sibcall_value_symbolic_sp32"
6250 [(set (match_operand 0 "" "=rf")
6251 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6252 (match_operand 2 "" "")))
6255 "* return output_sibcall(insn, operands[1]);"
6256 [(set_attr "type" "sibcall")])
6258 (define_insn "*sibcall_value_symbolic_sp64"
6259 [(set (match_operand 0 "" "")
6260 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6261 (match_operand 2 "" "")))
6264 "* return output_sibcall(insn, operands[1]);"
6265 [(set_attr "type" "sibcall")])
6268 ;; Special instructions.
6270 (define_expand "prologue"
6275 sparc_flat_expand_prologue ();
6277 sparc_expand_prologue ();
6281 ;; The "register window save" insn is modelled as follows. The dwarf2
6282 ;; information is manually added in emit_window_save.
6284 (define_insn "window_save"
6286 [(match_operand 0 "arith_operand" "rI")]
6289 "save\t%%sp, %0, %%sp"
6290 [(set_attr "type" "savew")])
6292 (define_expand "epilogue"
6297 sparc_flat_expand_epilogue (false);
6299 sparc_expand_epilogue (false);
6302 (define_expand "sibcall_epilogue"
6307 sparc_flat_expand_epilogue (false);
6309 sparc_expand_epilogue (false);
6313 (define_expand "eh_return"
6314 [(use (match_operand 0 "general_operand" ""))]
6317 emit_move_insn (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), operands[0]);
6318 emit_jump_insn (gen_eh_return_internal ());
6323 (define_insn_and_split "eh_return_internal"
6327 "epilogue_completed"
6331 sparc_flat_expand_epilogue (true);
6333 sparc_expand_epilogue (true);
6336 (define_expand "return"
6338 "sparc_can_use_return_insn_p ()"
6341 (define_insn "*return_internal"
6344 "* return output_return (insn);"
6345 [(set_attr "type" "return")
6346 (set (attr "length")
6347 (cond [(eq_attr "calls_eh_return" "true")
6348 (if_then_else (eq_attr "delayed_branch" "true")
6349 (if_then_else (ior (eq_attr "isa" "v9")
6350 (eq_attr "flat" "true"))
6353 (if_then_else (eq_attr "flat" "true")
6356 (ior (eq_attr "leaf_function" "true") (eq_attr "flat" "true"))
6357 (if_then_else (eq_attr "empty_delay_slot" "true")
6360 (eq_attr "empty_delay_slot" "true")
6361 (if_then_else (eq_attr "delayed_branch" "true")
6366 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6367 ;; all of memory. This blocks insns from being moved across this point.
6369 (define_insn "blockage"
6370 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6373 [(set_attr "length" "0")])
6375 (define_expand "probe_stack"
6376 [(set (match_operand 0 "memory_operand" "") (const_int 0))]
6380 = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
6383 (define_insn "probe_stack_range<P:mode>"
6384 [(set (match_operand:P 0 "register_operand" "=r")
6385 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6386 (match_operand:P 2 "register_operand" "r")]
6387 UNSPECV_PROBE_STACK_RANGE))]
6389 "* return output_probe_stack_range (operands[0], operands[2]);"
6390 [(set_attr "type" "multi")])
6392 ;; Prepare to return any type including a structure value.
6394 (define_expand "untyped_return"
6395 [(match_operand:BLK 0 "memory_operand" "")
6396 (match_operand 1 "" "")]
6399 rtx valreg1 = gen_rtx_REG (DImode, 24);
6400 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6401 rtx result = operands[0];
6403 if (! TARGET_ARCH64)
6405 rtx rtnreg = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
6406 rtx value = gen_reg_rtx (SImode);
6408 /* Fetch the instruction where we will return to and see if it's an unimp
6409 instruction (the most significant 10 bits will be zero). If so,
6410 update the return address to skip the unimp instruction. */
6411 emit_move_insn (value,
6412 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
6413 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6414 emit_insn (gen_update_return (rtnreg, value));
6417 /* Reload the function value registers. */
6418 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6419 emit_move_insn (valreg2,
6420 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6422 /* Put USE insns before the return. */
6426 /* Construct the return. */
6427 expand_naked_return ();
6432 ;; Adjust the return address conditionally. If the value of op1 is equal
6433 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6434 ;; This is technically *half* the check required by the 32-bit SPARC
6435 ;; psABI. This check only ensures that an "unimp" insn was written by
6436 ;; the caller, but doesn't check to see if the expected size matches
6437 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6438 ;; only used by the above code "untyped_return".
6440 (define_insn "update_return"
6441 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6442 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6445 if (flag_delayed_branch)
6446 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6448 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6450 [(set (attr "type") (const_string "multi"))
6451 (set (attr "length")
6452 (if_then_else (eq_attr "delayed_branch" "true")
6461 (define_expand "indirect_jump"
6462 [(set (pc) (match_operand 0 "address_operand" "p"))]
6466 (define_insn "*branch_sp32"
6467 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6470 [(set_attr "type" "uncond_branch")])
6472 (define_insn "*branch_sp64"
6473 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6476 [(set_attr "type" "uncond_branch")])
6478 (define_expand "save_stack_nonlocal"
6479 [(set (match_operand 0 "memory_operand" "")
6480 (match_operand 1 "register_operand" ""))
6481 (set (match_dup 2) (match_dup 3))]
6484 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
6485 operands[2] = adjust_address_nv (operands[0], Pmode, GET_MODE_SIZE (Pmode));
6486 operands[3] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6489 (define_expand "restore_stack_nonlocal"
6490 [(set (match_operand 0 "register_operand" "")
6491 (match_operand 1 "memory_operand" ""))]
6494 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
6497 (define_expand "nonlocal_goto"
6498 [(match_operand 0 "general_operand" "")
6499 (match_operand 1 "general_operand" "")
6500 (match_operand 2 "memory_operand" "")
6501 (match_operand 3 "memory_operand" "")]
6504 rtx r_label = copy_to_reg (operands[1]);
6505 rtx r_sp = adjust_address_nv (operands[2], Pmode, 0);
6506 rtx r_fp = operands[3];
6507 rtx r_i7 = adjust_address_nv (operands[2], Pmode, GET_MODE_SIZE (Pmode));
6509 /* We need to flush all the register windows so that their contents will
6510 be re-synchronized by the restore insn of the target function. */
6512 emit_insn (gen_flush_register_windows ());
6514 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
6515 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
6517 /* Restore frame pointer for containing function. */
6518 emit_move_insn (hard_frame_pointer_rtx, r_fp);
6519 emit_stack_restore (SAVE_NONLOCAL, r_sp);
6521 /* USE of hard_frame_pointer_rtx added for consistency;
6522 not clear if really needed. */
6523 emit_use (hard_frame_pointer_rtx);
6524 emit_use (stack_pointer_rtx);
6526 /* We need to smuggle the load of %i7 as it is a fixed register. */
6527 emit_jump_insn (gen_nonlocal_goto_internal (r_label, r_i7));
6532 (define_insn "nonlocal_goto_internal"
6533 [(unspec_volatile [(match_operand 0 "register_operand" "r")
6534 (match_operand 1 "memory_operand" "m")] UNSPECV_GOTO)]
6535 "GET_MODE (operands[0]) == Pmode && GET_MODE (operands[1]) == Pmode"
6537 if (flag_delayed_branch)
6540 return "jmp\t%0\n\t ldx\t%1, %%i7";
6542 return "jmp\t%0\n\t ld\t%1, %%i7";
6547 return "ldx\t%1, %%i7\n\tjmp\t%0\n\t nop";
6549 return "ld\t%1, %%i7\n\tjmp\t%0\n\t nop";
6552 [(set (attr "type") (const_string "multi"))
6553 (set (attr "length")
6554 (if_then_else (eq_attr "delayed_branch" "true")
6558 (define_expand "builtin_setjmp_receiver"
6559 [(label_ref (match_operand 0 "" ""))]
6562 load_got_register ();
6566 ;; Special insn to flush register windows.
6568 (define_insn "flush_register_windows"
6569 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
6571 { return TARGET_V9 ? "flushw" : "ta\t3"; }
6572 [(set_attr "type" "flushw")])
6574 ;; Special pattern for the FLUSH instruction.
6576 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
6577 ; of the define_insn otherwise missing a mode. We make "flush", aka
6578 ; gen_flush, the default one since sparc_initialize_trampoline uses
6579 ; it on SImode mem values.
6581 (define_insn "flush"
6582 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6584 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6585 [(set_attr "type" "iflush")])
6587 (define_insn "flushdi"
6588 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6590 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6591 [(set_attr "type" "iflush")])
6594 ;; Find first set instructions.
6596 ;; The scan instruction searches from the most significant bit while ffs
6597 ;; searches from the least significant bit. The bit index and treatment of
6598 ;; zero also differ. It takes at least 7 instructions to get the proper
6599 ;; result. Here is an obvious 8 instruction sequence.
6602 (define_insn "ffssi2"
6603 [(set (match_operand:SI 0 "register_operand" "=&r")
6604 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
6605 (clobber (match_scratch:SI 2 "=&r"))]
6606 "TARGET_SPARCLITE || TARGET_SPARCLET"
6608 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";
6610 [(set_attr "type" "multi")
6611 (set_attr "length" "8")])
6613 ;; ??? This should be a define expand, so that the extra instruction have
6614 ;; a chance of being optimized away.
6616 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
6617 ;; does, but no one uses that and we don't have a switch for it.
6619 ;(define_insn "ffsdi2"
6620 ; [(set (match_operand:DI 0 "register_operand" "=&r")
6621 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
6622 ; (clobber (match_scratch:DI 2 "=&r"))]
6624 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
6625 ; [(set_attr "type" "multi")
6626 ; (set_attr "length" "4")])
6630 ;; Peepholes go at the end.
6632 ;; Optimize consecutive loads or stores into ldd and std when possible.
6633 ;; The conditions in which we do this are very restricted and are
6634 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
6637 [(set (match_operand:SI 0 "memory_operand" "")
6639 (set (match_operand:SI 1 "memory_operand" "")
6642 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
6645 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
6648 [(set (match_operand:SI 0 "memory_operand" "")
6650 (set (match_operand:SI 1 "memory_operand" "")
6653 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
6656 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
6659 [(set (match_operand:SI 0 "register_operand" "")
6660 (match_operand:SI 1 "memory_operand" ""))
6661 (set (match_operand:SI 2 "register_operand" "")
6662 (match_operand:SI 3 "memory_operand" ""))]
6663 "registers_ok_for_ldd_peep (operands[0], operands[2])
6664 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6667 "operands[1] = widen_memory_access (operands[1], DImode, 0);
6668 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
6671 [(set (match_operand:SI 0 "memory_operand" "")
6672 (match_operand:SI 1 "register_operand" ""))
6673 (set (match_operand:SI 2 "memory_operand" "")
6674 (match_operand:SI 3 "register_operand" ""))]
6675 "registers_ok_for_ldd_peep (operands[1], operands[3])
6676 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6679 "operands[0] = widen_memory_access (operands[0], DImode, 0);
6680 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
6683 [(set (match_operand:SF 0 "register_operand" "")
6684 (match_operand:SF 1 "memory_operand" ""))
6685 (set (match_operand:SF 2 "register_operand" "")
6686 (match_operand:SF 3 "memory_operand" ""))]
6687 "registers_ok_for_ldd_peep (operands[0], operands[2])
6688 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6691 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
6692 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
6695 [(set (match_operand:SF 0 "memory_operand" "")
6696 (match_operand:SF 1 "register_operand" ""))
6697 (set (match_operand:SF 2 "memory_operand" "")
6698 (match_operand:SF 3 "register_operand" ""))]
6699 "registers_ok_for_ldd_peep (operands[1], operands[3])
6700 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6703 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
6704 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
6707 [(set (match_operand:SI 0 "register_operand" "")
6708 (match_operand:SI 1 "memory_operand" ""))
6709 (set (match_operand:SI 2 "register_operand" "")
6710 (match_operand:SI 3 "memory_operand" ""))]
6711 "registers_ok_for_ldd_peep (operands[2], operands[0])
6712 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6715 "operands[3] = widen_memory_access (operands[3], DImode, 0);
6716 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
6719 [(set (match_operand:SI 0 "memory_operand" "")
6720 (match_operand:SI 1 "register_operand" ""))
6721 (set (match_operand:SI 2 "memory_operand" "")
6722 (match_operand:SI 3 "register_operand" ""))]
6723 "registers_ok_for_ldd_peep (operands[3], operands[1])
6724 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6727 "operands[2] = widen_memory_access (operands[2], DImode, 0);
6728 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
6732 [(set (match_operand:SF 0 "register_operand" "")
6733 (match_operand:SF 1 "memory_operand" ""))
6734 (set (match_operand:SF 2 "register_operand" "")
6735 (match_operand:SF 3 "memory_operand" ""))]
6736 "registers_ok_for_ldd_peep (operands[2], operands[0])
6737 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6740 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
6741 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
6744 [(set (match_operand:SF 0 "memory_operand" "")
6745 (match_operand:SF 1 "register_operand" ""))
6746 (set (match_operand:SF 2 "memory_operand" "")
6747 (match_operand:SF 3 "register_operand" ""))]
6748 "registers_ok_for_ldd_peep (operands[3], operands[1])
6749 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6752 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
6753 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
6755 ;; Optimize the case of following a reg-reg move with a test
6756 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
6757 ;; This can result from a float to fix conversion.
6760 [(set (match_operand:SI 0 "register_operand" "")
6761 (match_operand:SI 1 "register_operand" ""))
6763 (compare:CC (match_operand:SI 2 "register_operand" "")
6765 "(rtx_equal_p (operands[2], operands[0])
6766 || rtx_equal_p (operands[2], operands[1]))
6767 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6768 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6769 [(parallel [(set (match_dup 0) (match_dup 1))
6771 (compare:CC (match_dup 1) (const_int 0)))])]
6775 [(set (match_operand:DI 0 "register_operand" "")
6776 (match_operand:DI 1 "register_operand" ""))
6778 (compare:CCX (match_operand:DI 2 "register_operand" "")
6781 && (rtx_equal_p (operands[2], operands[0])
6782 || rtx_equal_p (operands[2], operands[1]))
6783 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6784 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6785 [(parallel [(set (match_dup 0) (match_dup 1))
6787 (compare:CCX (match_dup 1) (const_int 0)))])]
6791 ;; Prefetch instructions.
6793 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
6794 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
6795 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
6797 (define_expand "prefetch"
6798 [(match_operand 0 "address_operand" "")
6799 (match_operand 1 "const_int_operand" "")
6800 (match_operand 2 "const_int_operand" "")]
6804 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
6806 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
6810 (define_insn "prefetch_64"
6811 [(prefetch (match_operand:DI 0 "address_operand" "p")
6812 (match_operand:DI 1 "const_int_operand" "n")
6813 (match_operand:DI 2 "const_int_operand" "n"))]
6816 static const char * const prefetch_instr[2][2] = {
6818 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
6819 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
6822 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
6823 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
6826 int read_or_write = INTVAL (operands[1]);
6827 int locality = INTVAL (operands[2]);
6829 gcc_assert (read_or_write == 0 || read_or_write == 1);
6830 gcc_assert (locality >= 0 && locality < 4);
6831 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
6833 [(set_attr "type" "load")])
6835 (define_insn "prefetch_32"
6836 [(prefetch (match_operand:SI 0 "address_operand" "p")
6837 (match_operand:SI 1 "const_int_operand" "n")
6838 (match_operand:SI 2 "const_int_operand" "n"))]
6841 static const char * const prefetch_instr[2][2] = {
6843 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
6844 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
6847 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
6848 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
6851 int read_or_write = INTVAL (operands[1]);
6852 int locality = INTVAL (operands[2]);
6854 gcc_assert (read_or_write == 0 || read_or_write == 1);
6855 gcc_assert (locality >= 0 && locality < 4);
6856 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
6858 [(set_attr "type" "load")])
6861 ;; Trap instructions.
6864 [(trap_if (const_int 1) (const_int 5))]
6867 [(set_attr "type" "trap")])
6869 (define_expand "ctrapsi4"
6870 [(trap_if (match_operator 0 "noov_compare_operator"
6871 [(match_operand:SI 1 "compare_operand" "")
6872 (match_operand:SI 2 "arith_operand" "")])
6873 (match_operand 3 ""))]
6875 "operands[1] = gen_compare_reg (operands[0]);
6876 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
6878 operands[2] = const0_rtx;")
6880 (define_expand "ctrapdi4"
6881 [(trap_if (match_operator 0 "noov_compare_operator"
6882 [(match_operand:DI 1 "compare_operand" "")
6883 (match_operand:DI 2 "arith_operand" "")])
6884 (match_operand 3 ""))]
6886 "operands[1] = gen_compare_reg (operands[0]);
6887 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
6889 operands[2] = const0_rtx;")
6893 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC 100) (const_int 0)])
6894 (match_operand:SI 1 "arith_operand" "rM"))]
6898 return "t%C0\t%%icc, %1";
6902 [(set_attr "type" "trap")])
6905 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX 100) (const_int 0)])
6906 (match_operand:SI 1 "arith_operand" "rM"))]
6909 [(set_attr "type" "trap")])
6912 ;; TLS support instructions.
6914 (define_insn "tgd_hi22"
6915 [(set (match_operand:SI 0 "register_operand" "=r")
6916 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
6919 "sethi\\t%%tgd_hi22(%a1), %0")
6921 (define_insn "tgd_lo10"
6922 [(set (match_operand:SI 0 "register_operand" "=r")
6923 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
6924 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
6927 "add\\t%1, %%tgd_lo10(%a2), %0")
6929 (define_insn "tgd_add32"
6930 [(set (match_operand:SI 0 "register_operand" "=r")
6931 (plus:SI (match_operand:SI 1 "register_operand" "r")
6932 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
6933 (match_operand 3 "tgd_symbolic_operand" "")]
6935 "TARGET_TLS && TARGET_ARCH32"
6936 "add\\t%1, %2, %0, %%tgd_add(%a3)")
6938 (define_insn "tgd_add64"
6939 [(set (match_operand:DI 0 "register_operand" "=r")
6940 (plus:DI (match_operand:DI 1 "register_operand" "r")
6941 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
6942 (match_operand 3 "tgd_symbolic_operand" "")]
6944 "TARGET_TLS && TARGET_ARCH64"
6945 "add\\t%1, %2, %0, %%tgd_add(%a3)")
6947 (define_insn "tgd_call32"
6948 [(set (match_operand 0 "register_operand" "=r")
6949 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
6950 (match_operand 2 "tgd_symbolic_operand" "")]
6952 (match_operand 3 "" "")))
6953 (clobber (reg:SI 15))]
6954 "TARGET_TLS && TARGET_ARCH32"
6955 "call\t%a1, %%tgd_call(%a2)%#"
6956 [(set_attr "type" "call")])
6958 (define_insn "tgd_call64"
6959 [(set (match_operand 0 "register_operand" "=r")
6960 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
6961 (match_operand 2 "tgd_symbolic_operand" "")]
6963 (match_operand 3 "" "")))
6964 (clobber (reg:DI 15))]
6965 "TARGET_TLS && TARGET_ARCH64"
6966 "call\t%a1, %%tgd_call(%a2)%#"
6967 [(set_attr "type" "call")])
6969 (define_insn "tldm_hi22"
6970 [(set (match_operand:SI 0 "register_operand" "=r")
6971 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
6973 "sethi\\t%%tldm_hi22(%&), %0")
6975 (define_insn "tldm_lo10"
6976 [(set (match_operand:SI 0 "register_operand" "=r")
6977 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
6978 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
6980 "add\\t%1, %%tldm_lo10(%&), %0")
6982 (define_insn "tldm_add32"
6983 [(set (match_operand:SI 0 "register_operand" "=r")
6984 (plus:SI (match_operand:SI 1 "register_operand" "r")
6985 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
6987 "TARGET_TLS && TARGET_ARCH32"
6988 "add\\t%1, %2, %0, %%tldm_add(%&)")
6990 (define_insn "tldm_add64"
6991 [(set (match_operand:DI 0 "register_operand" "=r")
6992 (plus:DI (match_operand:DI 1 "register_operand" "r")
6993 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
6995 "TARGET_TLS && TARGET_ARCH64"
6996 "add\\t%1, %2, %0, %%tldm_add(%&)")
6998 (define_insn "tldm_call32"
6999 [(set (match_operand 0 "register_operand" "=r")
7000 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7002 (match_operand 2 "" "")))
7003 (clobber (reg:SI 15))]
7004 "TARGET_TLS && TARGET_ARCH32"
7005 "call\t%a1, %%tldm_call(%&)%#"
7006 [(set_attr "type" "call")])
7008 (define_insn "tldm_call64"
7009 [(set (match_operand 0 "register_operand" "=r")
7010 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7012 (match_operand 2 "" "")))
7013 (clobber (reg:DI 15))]
7014 "TARGET_TLS && TARGET_ARCH64"
7015 "call\t%a1, %%tldm_call(%&)%#"
7016 [(set_attr "type" "call")])
7018 (define_insn "tldo_hix22"
7019 [(set (match_operand:SI 0 "register_operand" "=r")
7020 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7023 "sethi\\t%%tldo_hix22(%a1), %0")
7025 (define_insn "tldo_lox10"
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 "tld_symbolic_operand" "")]
7031 "xor\\t%1, %%tldo_lox10(%a2), %0")
7033 (define_insn "tldo_add32"
7034 [(set (match_operand:SI 0 "register_operand" "=r")
7035 (plus:SI (match_operand:SI 1 "register_operand" "r")
7036 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7037 (match_operand 3 "tld_symbolic_operand" "")]
7039 "TARGET_TLS && TARGET_ARCH32"
7040 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7042 (define_insn "tldo_add64"
7043 [(set (match_operand:DI 0 "register_operand" "=r")
7044 (plus:DI (match_operand:DI 1 "register_operand" "r")
7045 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7046 (match_operand 3 "tld_symbolic_operand" "")]
7048 "TARGET_TLS && TARGET_ARCH64"
7049 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7051 (define_insn "tie_hi22"
7052 [(set (match_operand:SI 0 "register_operand" "=r")
7053 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7056 "sethi\\t%%tie_hi22(%a1), %0")
7058 (define_insn "tie_lo10"
7059 [(set (match_operand:SI 0 "register_operand" "=r")
7060 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7061 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7064 "add\\t%1, %%tie_lo10(%a2), %0")
7066 (define_insn "tie_ld32"
7067 [(set (match_operand:SI 0 "register_operand" "=r")
7068 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7069 (match_operand:SI 2 "register_operand" "r")
7070 (match_operand 3 "tie_symbolic_operand" "")]
7072 "TARGET_TLS && TARGET_ARCH32"
7073 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7074 [(set_attr "type" "load")])
7076 (define_insn "tie_ld64"
7077 [(set (match_operand:DI 0 "register_operand" "=r")
7078 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7079 (match_operand:SI 2 "register_operand" "r")
7080 (match_operand 3 "tie_symbolic_operand" "")]
7082 "TARGET_TLS && TARGET_ARCH64"
7083 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7084 [(set_attr "type" "load")])
7086 (define_insn "tie_add32"
7087 [(set (match_operand:SI 0 "register_operand" "=r")
7088 (plus:SI (match_operand:SI 1 "register_operand" "r")
7089 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7090 (match_operand 3 "tie_symbolic_operand" "")]
7092 "TARGET_SUN_TLS && TARGET_ARCH32"
7093 "add\\t%1, %2, %0, %%tie_add(%a3)")
7095 (define_insn "tie_add64"
7096 [(set (match_operand:DI 0 "register_operand" "=r")
7097 (plus:DI (match_operand:DI 1 "register_operand" "r")
7098 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7099 (match_operand 3 "tie_symbolic_operand" "")]
7101 "TARGET_SUN_TLS && TARGET_ARCH64"
7102 "add\\t%1, %2, %0, %%tie_add(%a3)")
7104 (define_insn "tle_hix22_sp32"
7105 [(set (match_operand:SI 0 "register_operand" "=r")
7106 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7108 "TARGET_TLS && TARGET_ARCH32"
7109 "sethi\\t%%tle_hix22(%a1), %0")
7111 (define_insn "tle_lox10_sp32"
7112 [(set (match_operand:SI 0 "register_operand" "=r")
7113 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7114 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7116 "TARGET_TLS && TARGET_ARCH32"
7117 "xor\\t%1, %%tle_lox10(%a2), %0")
7119 (define_insn "tle_hix22_sp64"
7120 [(set (match_operand:DI 0 "register_operand" "=r")
7121 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7123 "TARGET_TLS && TARGET_ARCH64"
7124 "sethi\\t%%tle_hix22(%a1), %0")
7126 (define_insn "tle_lox10_sp64"
7127 [(set (match_operand:DI 0 "register_operand" "=r")
7128 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7129 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7131 "TARGET_TLS && TARGET_ARCH64"
7132 "xor\\t%1, %%tle_lox10(%a2), %0")
7134 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7135 (define_insn "*tldo_ldub_sp32"
7136 [(set (match_operand:QI 0 "register_operand" "=r")
7137 (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 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7143 [(set_attr "type" "load")
7144 (set_attr "us3load_type" "3cycle")])
7146 (define_insn "*tldo_ldub1_sp32"
7147 [(set (match_operand:HI 0 "register_operand" "=r")
7148 (zero_extend:HI (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 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7154 [(set_attr "type" "load")
7155 (set_attr "us3load_type" "3cycle")])
7157 (define_insn "*tldo_ldub2_sp32"
7158 [(set (match_operand:SI 0 "register_operand" "=r")
7159 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7160 (match_operand 3 "tld_symbolic_operand" "")]
7162 (match_operand:SI 1 "register_operand" "r")))))]
7163 "TARGET_TLS && TARGET_ARCH32"
7164 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7165 [(set_attr "type" "load")
7166 (set_attr "us3load_type" "3cycle")])
7168 (define_insn "*tldo_ldsb1_sp32"
7169 [(set (match_operand:HI 0 "register_operand" "=r")
7170 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7171 (match_operand 3 "tld_symbolic_operand" "")]
7173 (match_operand:SI 1 "register_operand" "r")))))]
7174 "TARGET_TLS && TARGET_ARCH32"
7175 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7176 [(set_attr "type" "sload")
7177 (set_attr "us3load_type" "3cycle")])
7179 (define_insn "*tldo_ldsb2_sp32"
7180 [(set (match_operand:SI 0 "register_operand" "=r")
7181 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7182 (match_operand 3 "tld_symbolic_operand" "")]
7184 (match_operand:SI 1 "register_operand" "r")))))]
7185 "TARGET_TLS && TARGET_ARCH32"
7186 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7187 [(set_attr "type" "sload")
7188 (set_attr "us3load_type" "3cycle")])
7190 (define_insn "*tldo_ldub_sp64"
7191 [(set (match_operand:QI 0 "register_operand" "=r")
7192 (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_ldub1_sp64"
7202 [(set (match_operand:HI 0 "register_operand" "=r")
7203 (zero_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 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7209 [(set_attr "type" "load")
7210 (set_attr "us3load_type" "3cycle")])
7212 (define_insn "*tldo_ldub2_sp64"
7213 [(set (match_operand:SI 0 "register_operand" "=r")
7214 (zero_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 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7220 [(set_attr "type" "load")
7221 (set_attr "us3load_type" "3cycle")])
7223 (define_insn "*tldo_ldub3_sp64"
7224 [(set (match_operand:DI 0 "register_operand" "=r")
7225 (zero_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 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7231 [(set_attr "type" "load")
7232 (set_attr "us3load_type" "3cycle")])
7234 (define_insn "*tldo_ldsb1_sp64"
7235 [(set (match_operand:HI 0 "register_operand" "=r")
7236 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7237 (match_operand 3 "tld_symbolic_operand" "")]
7239 (match_operand:DI 1 "register_operand" "r")))))]
7240 "TARGET_TLS && TARGET_ARCH64"
7241 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7242 [(set_attr "type" "sload")
7243 (set_attr "us3load_type" "3cycle")])
7245 (define_insn "*tldo_ldsb2_sp64"
7246 [(set (match_operand:SI 0 "register_operand" "=r")
7247 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7248 (match_operand 3 "tld_symbolic_operand" "")]
7250 (match_operand:DI 1 "register_operand" "r")))))]
7251 "TARGET_TLS && TARGET_ARCH64"
7252 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7253 [(set_attr "type" "sload")
7254 (set_attr "us3load_type" "3cycle")])
7256 (define_insn "*tldo_ldsb3_sp64"
7257 [(set (match_operand:DI 0 "register_operand" "=r")
7258 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7259 (match_operand 3 "tld_symbolic_operand" "")]
7261 (match_operand:DI 1 "register_operand" "r")))))]
7262 "TARGET_TLS && TARGET_ARCH64"
7263 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7264 [(set_attr "type" "sload")
7265 (set_attr "us3load_type" "3cycle")])
7267 (define_insn "*tldo_lduh_sp32"
7268 [(set (match_operand:HI 0 "register_operand" "=r")
7269 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7270 (match_operand 3 "tld_symbolic_operand" "")]
7272 (match_operand:SI 1 "register_operand" "r"))))]
7273 "TARGET_TLS && TARGET_ARCH32"
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_sp32"
7279 [(set (match_operand:SI 0 "register_operand" "=r")
7280 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7281 (match_operand 3 "tld_symbolic_operand" "")]
7283 (match_operand:SI 1 "register_operand" "r")))))]
7284 "TARGET_TLS && TARGET_ARCH32"
7285 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7286 [(set_attr "type" "load")
7287 (set_attr "us3load_type" "3cycle")])
7289 (define_insn "*tldo_ldsh1_sp32"
7290 [(set (match_operand:SI 0 "register_operand" "=r")
7291 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7292 (match_operand 3 "tld_symbolic_operand" "")]
7294 (match_operand:SI 1 "register_operand" "r")))))]
7295 "TARGET_TLS && TARGET_ARCH32"
7296 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7297 [(set_attr "type" "sload")
7298 (set_attr "us3load_type" "3cycle")])
7300 (define_insn "*tldo_lduh_sp64"
7301 [(set (match_operand:HI 0 "register_operand" "=r")
7302 (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 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7308 [(set_attr "type" "load")
7309 (set_attr "us3load_type" "3cycle")])
7311 (define_insn "*tldo_lduh1_sp64"
7312 [(set (match_operand:SI 0 "register_operand" "=r")
7313 (zero_extend:SI (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 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7319 [(set_attr "type" "load")
7320 (set_attr "us3load_type" "3cycle")])
7322 (define_insn "*tldo_lduh2_sp64"
7323 [(set (match_operand:DI 0 "register_operand" "=r")
7324 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7325 (match_operand 3 "tld_symbolic_operand" "")]
7327 (match_operand:DI 1 "register_operand" "r")))))]
7328 "TARGET_TLS && TARGET_ARCH64"
7329 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7330 [(set_attr "type" "load")
7331 (set_attr "us3load_type" "3cycle")])
7333 (define_insn "*tldo_ldsh1_sp64"
7334 [(set (match_operand:SI 0 "register_operand" "=r")
7335 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7336 (match_operand 3 "tld_symbolic_operand" "")]
7338 (match_operand:DI 1 "register_operand" "r")))))]
7339 "TARGET_TLS && TARGET_ARCH64"
7340 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7341 [(set_attr "type" "sload")
7342 (set_attr "us3load_type" "3cycle")])
7344 (define_insn "*tldo_ldsh2_sp64"
7345 [(set (match_operand:DI 0 "register_operand" "=r")
7346 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7347 (match_operand 3 "tld_symbolic_operand" "")]
7349 (match_operand:DI 1 "register_operand" "r")))))]
7350 "TARGET_TLS && TARGET_ARCH64"
7351 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7352 [(set_attr "type" "sload")
7353 (set_attr "us3load_type" "3cycle")])
7355 (define_insn "*tldo_lduw_sp32"
7356 [(set (match_operand:SI 0 "register_operand" "=r")
7357 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7358 (match_operand 3 "tld_symbolic_operand" "")]
7360 (match_operand:SI 1 "register_operand" "r"))))]
7361 "TARGET_TLS && TARGET_ARCH32"
7362 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7363 [(set_attr "type" "load")])
7365 (define_insn "*tldo_lduw_sp64"
7366 [(set (match_operand:SI 0 "register_operand" "=r")
7367 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7368 (match_operand 3 "tld_symbolic_operand" "")]
7370 (match_operand:DI 1 "register_operand" "r"))))]
7371 "TARGET_TLS && TARGET_ARCH64"
7372 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7373 [(set_attr "type" "load")])
7375 (define_insn "*tldo_lduw1_sp64"
7376 [(set (match_operand:DI 0 "register_operand" "=r")
7377 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7378 (match_operand 3 "tld_symbolic_operand" "")]
7380 (match_operand:DI 1 "register_operand" "r")))))]
7381 "TARGET_TLS && TARGET_ARCH64"
7382 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7383 [(set_attr "type" "load")])
7385 (define_insn "*tldo_ldsw1_sp64"
7386 [(set (match_operand:DI 0 "register_operand" "=r")
7387 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7388 (match_operand 3 "tld_symbolic_operand" "")]
7390 (match_operand:DI 1 "register_operand" "r")))))]
7391 "TARGET_TLS && TARGET_ARCH64"
7392 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7393 [(set_attr "type" "sload")
7394 (set_attr "us3load_type" "3cycle")])
7396 (define_insn "*tldo_ldx_sp64"
7397 [(set (match_operand:DI 0 "register_operand" "=r")
7398 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7399 (match_operand 3 "tld_symbolic_operand" "")]
7401 (match_operand:DI 1 "register_operand" "r"))))]
7402 "TARGET_TLS && TARGET_ARCH64"
7403 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7404 [(set_attr "type" "load")])
7406 (define_insn "*tldo_stb_sp32"
7407 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7408 (match_operand 3 "tld_symbolic_operand" "")]
7410 (match_operand:SI 1 "register_operand" "r")))
7411 (match_operand:QI 0 "register_operand" "=r"))]
7412 "TARGET_TLS && TARGET_ARCH32"
7413 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7414 [(set_attr "type" "store")])
7416 (define_insn "*tldo_stb_sp64"
7417 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7418 (match_operand 3 "tld_symbolic_operand" "")]
7420 (match_operand:DI 1 "register_operand" "r")))
7421 (match_operand:QI 0 "register_operand" "=r"))]
7422 "TARGET_TLS && TARGET_ARCH64"
7423 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7424 [(set_attr "type" "store")])
7426 (define_insn "*tldo_sth_sp32"
7427 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7428 (match_operand 3 "tld_symbolic_operand" "")]
7430 (match_operand:SI 1 "register_operand" "r")))
7431 (match_operand:HI 0 "register_operand" "=r"))]
7432 "TARGET_TLS && TARGET_ARCH32"
7433 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7434 [(set_attr "type" "store")])
7436 (define_insn "*tldo_sth_sp64"
7437 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7438 (match_operand 3 "tld_symbolic_operand" "")]
7440 (match_operand:DI 1 "register_operand" "r")))
7441 (match_operand:HI 0 "register_operand" "=r"))]
7442 "TARGET_TLS && TARGET_ARCH64"
7443 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7444 [(set_attr "type" "store")])
7446 (define_insn "*tldo_stw_sp32"
7447 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7448 (match_operand 3 "tld_symbolic_operand" "")]
7450 (match_operand:SI 1 "register_operand" "r")))
7451 (match_operand:SI 0 "register_operand" "=r"))]
7452 "TARGET_TLS && TARGET_ARCH32"
7453 "st\t%0, [%1 + %2], %%tldo_add(%3)"
7454 [(set_attr "type" "store")])
7456 (define_insn "*tldo_stw_sp64"
7457 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7458 (match_operand 3 "tld_symbolic_operand" "")]
7460 (match_operand:DI 1 "register_operand" "r")))
7461 (match_operand:SI 0 "register_operand" "=r"))]
7462 "TARGET_TLS && TARGET_ARCH64"
7463 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7464 [(set_attr "type" "store")])
7466 (define_insn "*tldo_stx_sp64"
7467 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7468 (match_operand 3 "tld_symbolic_operand" "")]
7470 (match_operand:DI 1 "register_operand" "r")))
7471 (match_operand:DI 0 "register_operand" "=r"))]
7472 "TARGET_TLS && TARGET_ARCH64"
7473 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7474 [(set_attr "type" "store")])
7477 ;; Stack protector instructions.
7479 (define_expand "stack_protect_set"
7480 [(match_operand 0 "memory_operand" "")
7481 (match_operand 1 "memory_operand" "")]
7484 #ifdef TARGET_THREAD_SSP_OFFSET
7485 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7486 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7487 operands[1] = gen_rtx_MEM (Pmode, addr);
7490 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7492 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7496 (define_insn "stack_protect_setsi"
7497 [(set (match_operand:SI 0 "memory_operand" "=m")
7498 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7499 (set (match_scratch:SI 2 "=&r") (const_int 0))]
7501 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
7502 [(set_attr "type" "multi")
7503 (set_attr "length" "3")])
7505 (define_insn "stack_protect_setdi"
7506 [(set (match_operand:DI 0 "memory_operand" "=m")
7507 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7508 (set (match_scratch:DI 2 "=&r") (const_int 0))]
7510 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
7511 [(set_attr "type" "multi")
7512 (set_attr "length" "3")])
7514 (define_expand "stack_protect_test"
7515 [(match_operand 0 "memory_operand" "")
7516 (match_operand 1 "memory_operand" "")
7517 (match_operand 2 "" "")]
7521 #ifdef TARGET_THREAD_SSP_OFFSET
7522 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7523 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7524 operands[1] = gen_rtx_MEM (Pmode, addr);
7528 result = gen_reg_rtx (Pmode);
7529 emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
7530 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7531 emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
7535 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7536 result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
7537 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7538 emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
7543 (define_insn "stack_protect_testsi"
7545 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
7546 (match_operand:SI 1 "memory_operand" "m")]
7548 (set (match_scratch:SI 3 "=r") (const_int 0))
7549 (clobber (match_scratch:SI 2 "=&r"))]
7551 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
7552 [(set_attr "type" "multi")
7553 (set_attr "length" "4")])
7555 (define_insn "stack_protect_testdi"
7556 [(set (match_operand:DI 0 "register_operand" "=&r")
7557 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7558 (match_operand:DI 2 "memory_operand" "m")]
7560 (set (match_scratch:DI 3 "=r") (const_int 0))]
7562 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
7563 [(set_attr "type" "multi")
7564 (set_attr "length" "4")])
7567 ;; Vector instructions.
7569 (define_insn "addv2si3"
7570 [(set (match_operand:V2SI 0 "register_operand" "=e")
7571 (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7572 (match_operand:V2SI 2 "register_operand" "e")))]
7574 "fpadd32\t%1, %2, %0"
7575 [(set_attr "type" "fga")
7576 (set_attr "fptype" "double")])
7578 (define_insn "addv4hi3"
7579 [(set (match_operand:V4HI 0 "register_operand" "=e")
7580 (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7581 (match_operand:V4HI 2 "register_operand" "e")))]
7583 "fpadd16\t%1, %2, %0"
7584 [(set_attr "type" "fga")
7585 (set_attr "fptype" "double")])
7587 ;; fpadd32s is emitted by the addsi3 pattern.
7589 (define_insn "addv2hi3"
7590 [(set (match_operand:V2HI 0 "register_operand" "=f")
7591 (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7592 (match_operand:V2HI 2 "register_operand" "f")))]
7594 "fpadd16s\t%1, %2, %0"
7595 [(set_attr "type" "fga")
7596 (set_attr "fptype" "single")])
7598 (define_insn "subv2si3"
7599 [(set (match_operand:V2SI 0 "register_operand" "=e")
7600 (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7601 (match_operand:V2SI 2 "register_operand" "e")))]
7603 "fpsub32\t%1, %2, %0"
7604 [(set_attr "type" "fga")
7605 (set_attr "fptype" "double")])
7607 (define_insn "subv4hi3"
7608 [(set (match_operand:V4HI 0 "register_operand" "=e")
7609 (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7610 (match_operand:V4HI 2 "register_operand" "e")))]
7612 "fpsub16\t%1, %2, %0"
7613 [(set_attr "type" "fga")
7614 (set_attr "fptype" "double")])
7616 ;; fpsub32s is emitted by the subsi3 pattern.
7618 (define_insn "subv2hi3"
7619 [(set (match_operand:V2HI 0 "register_operand" "=f")
7620 (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7621 (match_operand:V2HI 2 "register_operand" "f")))]
7623 "fpsub16s\t%1, %2, %0"
7624 [(set_attr "type" "fga")
7625 (set_attr "fptype" "single")])
7627 ;; All other logical instructions have integer equivalents so they
7628 ;; are defined together.
7630 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
7632 (define_insn "*nand<V64:mode>_vis"
7633 [(set (match_operand:V64 0 "register_operand" "=e")
7634 (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
7635 (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
7638 [(set_attr "type" "fga")
7639 (set_attr "fptype" "double")])
7641 (define_insn "*nand<V32:mode>_vis"
7642 [(set (match_operand:V32 0 "register_operand" "=f")
7643 (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
7644 (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
7646 "fnands\t%1, %2, %0"
7647 [(set_attr "type" "fga")
7648 (set_attr "fptype" "single")])
7650 ;; Hard to generate VIS instructions. We have builtins for these.
7652 (define_insn "fpack16_vis"
7653 [(set (match_operand:V4QI 0 "register_operand" "=f")
7654 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
7658 [(set_attr "type" "fga")
7659 (set_attr "fptype" "double")])
7661 (define_insn "fpackfix_vis"
7662 [(set (match_operand:V2HI 0 "register_operand" "=f")
7663 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
7667 [(set_attr "type" "fga")
7668 (set_attr "fptype" "double")])
7670 (define_insn "fpack32_vis"
7671 [(set (match_operand:V8QI 0 "register_operand" "=e")
7672 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
7673 (match_operand:V8QI 2 "register_operand" "e")]
7676 "fpack32\t%1, %2, %0"
7677 [(set_attr "type" "fga")
7678 (set_attr "fptype" "double")])
7680 (define_insn "fexpand_vis"
7681 [(set (match_operand:V4HI 0 "register_operand" "=e")
7682 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
7686 [(set_attr "type" "fga")
7687 (set_attr "fptype" "double")])
7689 ;; It may be possible to describe this operation as (1 indexed):
7690 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
7691 ;; 1,5,10,14,19,23,28,32)
7692 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
7693 ;; because vec_merge expects all the operands to be of the same type.
7694 (define_insn "fpmerge_vis"
7695 [(set (match_operand:V8QI 0 "register_operand" "=e")
7696 (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
7697 (match_operand:V4QI 2 "register_operand" "f")]
7700 "fpmerge\t%1, %2, %0"
7701 [(set_attr "type" "fga")
7702 (set_attr "fptype" "double")])
7704 ;; Partitioned multiply instructions
7705 (define_insn "fmul8x16_vis"
7706 [(set (match_operand:V4HI 0 "register_operand" "=e")
7707 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7708 (match_operand:V4HI 2 "register_operand" "e")))]
7710 "fmul8x16\t%1, %2, %0"
7711 [(set_attr "type" "fpmul")
7712 (set_attr "fptype" "double")])
7714 ;; Only one of the following two insns can be a multiply.
7715 (define_insn "fmul8x16au_vis"
7716 [(set (match_operand:V4HI 0 "register_operand" "=e")
7717 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7718 (match_operand:V2HI 2 "register_operand" "f")))]
7720 "fmul8x16au\t%1, %2, %0"
7721 [(set_attr "type" "fpmul")
7722 (set_attr "fptype" "double")])
7724 (define_insn "fmul8x16al_vis"
7725 [(set (match_operand:V4HI 0 "register_operand" "=e")
7726 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
7727 (match_operand:V2HI 2 "register_operand" "f")]
7730 "fmul8x16al\t%1, %2, %0"
7731 [(set_attr "type" "fpmul")
7732 (set_attr "fptype" "double")])
7734 ;; Only one of the following two insns can be a multiply.
7735 (define_insn "fmul8sux16_vis"
7736 [(set (match_operand:V4HI 0 "register_operand" "=e")
7737 (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
7738 (match_operand:V4HI 2 "register_operand" "e")))]
7740 "fmul8sux16\t%1, %2, %0"
7741 [(set_attr "type" "fpmul")
7742 (set_attr "fptype" "double")])
7744 (define_insn "fmul8ulx16_vis"
7745 [(set (match_operand:V4HI 0 "register_operand" "=e")
7746 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
7747 (match_operand:V4HI 2 "register_operand" "e")]
7750 "fmul8ulx16\t%1, %2, %0"
7751 [(set_attr "type" "fpmul")
7752 (set_attr "fptype" "double")])
7754 ;; Only one of the following two insns can be a multiply.
7755 (define_insn "fmuld8sux16_vis"
7756 [(set (match_operand:V2SI 0 "register_operand" "=e")
7757 (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
7758 (match_operand:V2HI 2 "register_operand" "f")))]
7760 "fmuld8sux16\t%1, %2, %0"
7761 [(set_attr "type" "fpmul")
7762 (set_attr "fptype" "double")])
7764 (define_insn "fmuld8ulx16_vis"
7765 [(set (match_operand:V2SI 0 "register_operand" "=e")
7766 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
7767 (match_operand:V2HI 2 "register_operand" "f")]
7770 "fmuld8ulx16\t%1, %2, %0"
7771 [(set_attr "type" "fpmul")
7772 (set_attr "fptype" "double")])
7774 ;; Using faligndata only makes sense after an alignaddr since the choice of
7775 ;; bytes to take out of each operand is dependent on the results of the last
7777 (define_insn "faligndata<V64I:mode>_vis"
7778 [(set (match_operand:V64I 0 "register_operand" "=e")
7779 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
7780 (match_operand:V64I 2 "register_operand" "e")]
7783 "faligndata\t%1, %2, %0"
7784 [(set_attr "type" "fga")
7785 (set_attr "fptype" "double")])
7787 (define_insn "alignaddr<P:mode>_vis"
7788 [(set (match_operand:P 0 "register_operand" "=r")
7789 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
7790 (match_operand:P 2 "register_or_zero_operand" "rJ")]
7793 "alignaddr\t%r1, %r2, %0")
7795 (define_insn "pdist_vis"
7796 [(set (match_operand:DI 0 "register_operand" "=e")
7797 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
7798 (match_operand:V8QI 2 "register_operand" "e")
7799 (match_operand:DI 3 "register_operand" "0")]
7803 [(set_attr "type" "fga")
7804 (set_attr "fptype" "double")])