1 ;; Machine description for SPARC chip for GCC
2 ;; Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;; 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 ;; Free Software Foundation, Inc.
5 ;; Contributed by Michael Tiemann (tiemann@cygnus.com)
6 ;; 64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
9 ;; This file is part of GCC.
11 ;; GCC is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 3, or (at your option)
16 ;; GCC is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ;; GNU General Public License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GCC; see the file COPYING3. If not see
23 ;; <http://www.gnu.org/licenses/>.
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 (UNSPEC_UPDATE_RETURN 1)
30 (UNSPEC_LOAD_PCREL_SYM 2)
31 (UNSPEC_MOVE_PIC_LABEL 5)
37 (UNSPEC_EMB_TEXTUHI 13)
38 (UNSPEC_EMB_TEXTHI 14)
39 (UNSPEC_EMB_TEXTULO 15)
41 (UNSPEC_MOVE_GOTDATA 19)
50 (UNSPEC_TLSLD_BASE 35)
78 (UNSPECV_PROBE_STACK_RANGE 11)
82 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
83 (define_mode_iterator I [QI HI SI DI])
84 (define_mode_iterator F [SF DF TF])
86 ;; We don't define V1SI because SI should work just fine.
87 (define_mode_iterator V32 [SF V2HI V4QI])
88 (define_mode_iterator V32I [SI V2HI V4QI])
90 (define_mode_iterator V64 [DF V2SI V4HI V8QI])
91 (define_mode_iterator V64I [DI V2SI V4HI V8QI])
93 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
94 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
95 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
96 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
97 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
100 ;; Attribute for cpu type.
101 ;; These must match the values for enum processor_type in sparc.h.
108 hypersparc,sparclite86x,
115 (const (symbol_ref "sparc_cpu_attr")))
117 ;; Attribute for the instruction set.
118 ;; At present we only need to distinguish v9/!v9, but for clarity we
119 ;; test TARGET_V8 too.
120 (define_attr "isa" "v7,v8,v9,sparclet"
122 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
123 (symbol_ref "TARGET_V8") (const_string "v8")
124 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
125 (const_string "v7"))))
131 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
139 fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,
142 multi,savew,flushw,iflush,trap"
143 (const_string "ialu"))
145 ;; True if branch/call has empty delay slot and will emit a nop in it
146 (define_attr "empty_delay_slot" "false,true"
147 (symbol_ref "(empty_delay_slot (insn)
148 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
150 (define_attr "branch_type" "none,icc,fcc,reg"
151 (const_string "none"))
153 (define_attr "pic" "false,true"
154 (symbol_ref "(flag_pic != 0 ? PIC_TRUE : PIC_FALSE)"))
156 (define_attr "calls_alloca" "false,true"
157 (symbol_ref "(cfun->calls_alloca != 0
158 ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)"))
160 (define_attr "calls_eh_return" "false,true"
161 (symbol_ref "(crtl->calls_eh_return != 0
162 ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)"))
164 (define_attr "leaf_function" "false,true"
165 (symbol_ref "(current_function_uses_only_leaf_regs != 0
166 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
168 (define_attr "delayed_branch" "false,true"
169 (symbol_ref "(flag_delayed_branch != 0
170 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
172 ;; Length (in # of insns).
173 ;; Beware that setting a length greater or equal to 3 for conditional branches
174 ;; has a side-effect (see output_cbranch and output_v9branch).
175 (define_attr "length" ""
176 (cond [(eq_attr "type" "uncond_branch,call")
177 (if_then_else (eq_attr "empty_delay_slot" "true")
180 (eq_attr "type" "sibcall")
181 (if_then_else (eq_attr "leaf_function" "true")
182 (if_then_else (eq_attr "empty_delay_slot" "true")
185 (if_then_else (eq_attr "empty_delay_slot" "true")
188 (eq_attr "branch_type" "icc")
189 (if_then_else (match_operand 0 "noov_compare64_operator" "")
190 (if_then_else (lt (pc) (match_dup 1))
191 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
192 (if_then_else (eq_attr "empty_delay_slot" "true")
195 (if_then_else (eq_attr "empty_delay_slot" "true")
198 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
199 (if_then_else (eq_attr "empty_delay_slot" "true")
202 (if_then_else (eq_attr "empty_delay_slot" "true")
205 (if_then_else (eq_attr "empty_delay_slot" "true")
208 (eq_attr "branch_type" "fcc")
209 (if_then_else (match_operand 0 "fcc0_register_operand" "")
210 (if_then_else (eq_attr "empty_delay_slot" "true")
211 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
214 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
217 (if_then_else (lt (pc) (match_dup 2))
218 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
219 (if_then_else (eq_attr "empty_delay_slot" "true")
222 (if_then_else (eq_attr "empty_delay_slot" "true")
225 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
226 (if_then_else (eq_attr "empty_delay_slot" "true")
229 (if_then_else (eq_attr "empty_delay_slot" "true")
232 (eq_attr "branch_type" "reg")
233 (if_then_else (lt (pc) (match_dup 2))
234 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
235 (if_then_else (eq_attr "empty_delay_slot" "true")
238 (if_then_else (eq_attr "empty_delay_slot" "true")
241 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
242 (if_then_else (eq_attr "empty_delay_slot" "true")
245 (if_then_else (eq_attr "empty_delay_slot" "true")
251 (define_attr "fptype" "single,double"
252 (const_string "single"))
254 ;; UltraSPARC-III integer load type.
255 (define_attr "us3load_type" "2cycle,3cycle"
256 (const_string "2cycle"))
258 (define_asm_attributes
259 [(set_attr "length" "2")
260 (set_attr "type" "multi")])
262 ;; Attributes for instruction and branch scheduling
263 (define_attr "tls_call_delay" "false,true"
264 (symbol_ref "(tls_call_delay (insn)
265 ? TLS_CALL_DELAY_TRUE : TLS_CALL_DELAY_FALSE)"))
267 (define_attr "in_call_delay" "false,true"
268 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
269 (const_string "false")
270 (eq_attr "type" "load,fpload,store,fpstore")
271 (if_then_else (eq_attr "length" "1")
272 (const_string "true")
273 (const_string "false"))]
274 (if_then_else (and (eq_attr "length" "1")
275 (eq_attr "tls_call_delay" "true"))
276 (const_string "true")
277 (const_string "false"))))
279 (define_attr "eligible_for_sibcall_delay" "false,true"
280 (symbol_ref "(eligible_for_sibcall_delay (insn)
281 ? ELIGIBLE_FOR_SIBCALL_DELAY_TRUE
282 : ELIGIBLE_FOR_SIBCALL_DELAY_FALSE)"))
284 (define_attr "eligible_for_return_delay" "false,true"
285 (symbol_ref "(eligible_for_return_delay (insn)
286 ? ELIGIBLE_FOR_RETURN_DELAY_TRUE
287 : ELIGIBLE_FOR_RETURN_DELAY_FALSE)"))
289 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
290 ;; branches. This would allow us to remove the nop always inserted before
291 ;; a floating point branch.
293 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
294 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
295 ;; This is because doing so will add several pipeline stalls to the path
296 ;; that the load/store did not come from. Unfortunately, there is no way
297 ;; to prevent fill_eager_delay_slots from using load/store without completely
298 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
299 ;; because it prevents us from moving back the final store of inner loops.
301 (define_attr "in_branch_delay" "false,true"
302 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
303 (eq_attr "length" "1"))
304 (const_string "true")
305 (const_string "false")))
307 (define_attr "in_uncond_branch_delay" "false,true"
308 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
309 (eq_attr "length" "1"))
310 (const_string "true")
311 (const_string "false")))
313 (define_attr "in_annul_branch_delay" "false,true"
314 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
315 (eq_attr "length" "1"))
316 (const_string "true")
317 (const_string "false")))
319 (define_delay (eq_attr "type" "call")
320 [(eq_attr "in_call_delay" "true") (nil) (nil)])
322 (define_delay (eq_attr "type" "sibcall")
323 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
325 (define_delay (eq_attr "type" "branch")
326 [(eq_attr "in_branch_delay" "true")
327 (nil) (eq_attr "in_annul_branch_delay" "true")])
329 (define_delay (eq_attr "type" "uncond_branch")
330 [(eq_attr "in_uncond_branch_delay" "true")
333 (define_delay (eq_attr "type" "return")
334 [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
337 ;; Include SPARC DFA schedulers
339 (include "cypress.md")
340 (include "supersparc.md")
341 (include "hypersparc.md")
342 (include "sparclet.md")
343 (include "ultra1_2.md")
344 (include "ultra3.md")
345 (include "niagara.md")
346 (include "niagara2.md")
349 ;; Operand and operator predicates and constraints
351 (include "predicates.md")
352 (include "constraints.md")
355 ;; Compare instructions.
357 ;; These are just the DEFINE_INSNs to match the patterns and the
358 ;; DEFINE_SPLITs for some of the scc insns that actually require
359 ;; more than one machine instruction. DEFINE_EXPANDs are further down.
361 ;; The compare DEFINE_INSNs.
363 (define_insn "*cmpsi_insn"
365 (compare:CC (match_operand:SI 0 "register_operand" "r")
366 (match_operand:SI 1 "arith_operand" "rI")))]
369 [(set_attr "type" "compare")])
371 (define_insn "*cmpdi_sp64"
373 (compare:CCX (match_operand:DI 0 "register_operand" "r")
374 (match_operand:DI 1 "arith_operand" "rI")))]
377 [(set_attr "type" "compare")])
379 (define_insn "*cmpsf_fpe"
380 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
381 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
382 (match_operand:SF 2 "register_operand" "f")))]
386 return "fcmpes\t%0, %1, %2";
387 return "fcmpes\t%1, %2";
389 [(set_attr "type" "fpcmp")])
391 (define_insn "*cmpdf_fpe"
392 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
393 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
394 (match_operand:DF 2 "register_operand" "e")))]
398 return "fcmped\t%0, %1, %2";
399 return "fcmped\t%1, %2";
401 [(set_attr "type" "fpcmp")
402 (set_attr "fptype" "double")])
404 (define_insn "*cmptf_fpe"
405 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
406 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
407 (match_operand:TF 2 "register_operand" "e")))]
408 "TARGET_FPU && TARGET_HARD_QUAD"
411 return "fcmpeq\t%0, %1, %2";
412 return "fcmpeq\t%1, %2";
414 [(set_attr "type" "fpcmp")])
416 (define_insn "*cmpsf_fp"
417 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
418 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
419 (match_operand:SF 2 "register_operand" "f")))]
423 return "fcmps\t%0, %1, %2";
424 return "fcmps\t%1, %2";
426 [(set_attr "type" "fpcmp")])
428 (define_insn "*cmpdf_fp"
429 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
430 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
431 (match_operand:DF 2 "register_operand" "e")))]
435 return "fcmpd\t%0, %1, %2";
436 return "fcmpd\t%1, %2";
438 [(set_attr "type" "fpcmp")
439 (set_attr "fptype" "double")])
441 (define_insn "*cmptf_fp"
442 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
443 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
444 (match_operand:TF 2 "register_operand" "e")))]
445 "TARGET_FPU && TARGET_HARD_QUAD"
448 return "fcmpq\t%0, %1, %2";
449 return "fcmpq\t%1, %2";
451 [(set_attr "type" "fpcmp")])
453 ;; Next come the scc insns.
455 (define_expand "cstoresi4"
456 [(use (match_operator 1 "comparison_operator"
457 [(match_operand:SI 2 "compare_operand" "")
458 (match_operand:SI 3 "arith_operand" "")]))
459 (clobber (match_operand:SI 0 "register_operand"))]
462 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
463 operands[2] = force_reg (SImode, operands[2]);
464 if (emit_scc_insn (operands)) DONE; else FAIL;
467 (define_expand "cstoredi4"
468 [(use (match_operator 1 "comparison_operator"
469 [(match_operand:DI 2 "compare_operand" "")
470 (match_operand:DI 3 "arith_operand" "")]))
471 (clobber (match_operand:SI 0 "register_operand"))]
474 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
475 operands[2] = force_reg (DImode, operands[2]);
476 if (emit_scc_insn (operands)) DONE; else FAIL;
479 (define_expand "cstore<F:mode>4"
480 [(use (match_operator 1 "comparison_operator"
481 [(match_operand:F 2 "register_operand" "")
482 (match_operand:F 3 "register_operand" "")]))
483 (clobber (match_operand:SI 0 "register_operand"))]
485 { if (emit_scc_insn (operands)) DONE; else FAIL; })
489 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
490 ;; generate addcc/subcc instructions.
492 (define_expand "seqsi_special"
494 (xor:SI (match_operand:SI 1 "register_operand" "")
495 (match_operand:SI 2 "register_operand" "")))
496 (parallel [(set (match_operand:SI 0 "register_operand" "")
497 (eq:SI (match_dup 3) (const_int 0)))
498 (clobber (reg:CC 100))])]
500 { operands[3] = gen_reg_rtx (SImode); })
502 (define_expand "seqdi_special"
504 (xor:DI (match_operand:DI 1 "register_operand" "")
505 (match_operand:DI 2 "register_operand" "")))
506 (set (match_operand:SI 0 "register_operand" "")
507 (eq:SI (match_dup 3) (const_int 0)))]
509 { operands[3] = gen_reg_rtx (DImode); })
511 (define_expand "snesi_special"
513 (xor:SI (match_operand:SI 1 "register_operand" "")
514 (match_operand:SI 2 "register_operand" "")))
515 (parallel [(set (match_operand:SI 0 "register_operand" "")
516 (ne:SI (match_dup 3) (const_int 0)))
517 (clobber (reg:CC 100))])]
519 { operands[3] = gen_reg_rtx (SImode); })
521 (define_expand "snedi_special"
523 (xor:DI (match_operand:DI 1 "register_operand" "")
524 (match_operand:DI 2 "register_operand" "")))
525 (set (match_operand:SI 0 "register_operand" "")
526 (ne:SI (match_dup 3) (const_int 0)))]
528 { operands[3] = gen_reg_rtx (DImode); })
531 ;; Now the DEFINE_INSNs for the scc cases.
533 ;; The SEQ and SNE patterns are special because they can be done
534 ;; without any branching and do not involve a COMPARE. We want
535 ;; them to always use the splits below so the results can be
538 (define_insn_and_split "*snesi_zero"
539 [(set (match_operand:SI 0 "register_operand" "=r")
540 (ne:SI (match_operand:SI 1 "register_operand" "r")
542 (clobber (reg:CC 100))]
546 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
548 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
550 [(set_attr "length" "2")])
552 (define_insn_and_split "*neg_snesi_zero"
553 [(set (match_operand:SI 0 "register_operand" "=r")
554 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
556 (clobber (reg:CC 100))]
560 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
562 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
564 [(set_attr "length" "2")])
566 (define_insn_and_split "*snesi_zero_extend"
567 [(set (match_operand:DI 0 "register_operand" "=r")
568 (ne:DI (match_operand:SI 1 "register_operand" "r")
570 (clobber (reg:CC 100))]
574 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
577 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
579 (ltu:SI (reg:CC_NOOV 100)
582 [(set_attr "length" "2")])
584 (define_insn_and_split "*snedi_zero"
585 [(set (match_operand:DI 0 "register_operand" "=&r")
586 (ne:DI (match_operand:DI 1 "register_operand" "r")
590 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
591 [(set (match_dup 0) (const_int 0))
592 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
597 [(set_attr "length" "2")])
599 (define_insn_and_split "*neg_snedi_zero"
600 [(set (match_operand:DI 0 "register_operand" "=&r")
601 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
605 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
606 [(set (match_dup 0) (const_int 0))
607 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
612 [(set_attr "length" "2")])
614 (define_insn_and_split "*snedi_zero_trunc"
615 [(set (match_operand:SI 0 "register_operand" "=&r")
616 (ne:SI (match_operand:DI 1 "register_operand" "r")
620 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
621 [(set (match_dup 0) (const_int 0))
622 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
627 [(set_attr "length" "2")])
629 (define_insn_and_split "*seqsi_zero"
630 [(set (match_operand:SI 0 "register_operand" "=r")
631 (eq:SI (match_operand:SI 1 "register_operand" "r")
633 (clobber (reg:CC 100))]
637 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
639 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
641 [(set_attr "length" "2")])
643 (define_insn_and_split "*neg_seqsi_zero"
644 [(set (match_operand:SI 0 "register_operand" "=r")
645 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
647 (clobber (reg:CC 100))]
651 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
653 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
655 [(set_attr "length" "2")])
657 (define_insn_and_split "*seqsi_zero_extend"
658 [(set (match_operand:DI 0 "register_operand" "=r")
659 (eq:DI (match_operand:SI 1 "register_operand" "r")
661 (clobber (reg:CC 100))]
665 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
668 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
670 (ltu:SI (reg:CC_NOOV 100)
673 [(set_attr "length" "2")])
675 (define_insn_and_split "*seqdi_zero"
676 [(set (match_operand:DI 0 "register_operand" "=&r")
677 (eq:DI (match_operand:DI 1 "register_operand" "r")
681 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
682 [(set (match_dup 0) (const_int 0))
683 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
688 [(set_attr "length" "2")])
690 (define_insn_and_split "*neg_seqdi_zero"
691 [(set (match_operand:DI 0 "register_operand" "=&r")
692 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
696 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
697 [(set (match_dup 0) (const_int 0))
698 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
703 [(set_attr "length" "2")])
705 (define_insn_and_split "*seqdi_zero_trunc"
706 [(set (match_operand:SI 0 "register_operand" "=&r")
707 (eq:SI (match_operand:DI 1 "register_operand" "r")
711 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
712 [(set (match_dup 0) (const_int 0))
713 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
718 [(set_attr "length" "2")])
720 ;; We can also do (x + (i == 0)) and related, so put them in.
721 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
724 (define_insn_and_split "*x_plus_i_ne_0"
725 [(set (match_operand:SI 0 "register_operand" "=r")
726 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
728 (match_operand:SI 2 "register_operand" "r")))
729 (clobber (reg:CC 100))]
733 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
735 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
738 [(set_attr "length" "2")])
740 (define_insn_and_split "*x_minus_i_ne_0"
741 [(set (match_operand:SI 0 "register_operand" "=r")
742 (minus:SI (match_operand:SI 2 "register_operand" "r")
743 (ne:SI (match_operand:SI 1 "register_operand" "r")
745 (clobber (reg:CC 100))]
749 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
751 (set (match_dup 0) (minus:SI (match_dup 2)
752 (ltu:SI (reg:CC 100) (const_int 0))))]
754 [(set_attr "length" "2")])
756 (define_insn_and_split "*x_plus_i_eq_0"
757 [(set (match_operand:SI 0 "register_operand" "=r")
758 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
760 (match_operand:SI 2 "register_operand" "r")))
761 (clobber (reg:CC 100))]
765 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
767 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
770 [(set_attr "length" "2")])
772 (define_insn_and_split "*x_minus_i_eq_0"
773 [(set (match_operand:SI 0 "register_operand" "=r")
774 (minus:SI (match_operand:SI 2 "register_operand" "r")
775 (eq:SI (match_operand:SI 1 "register_operand" "r")
777 (clobber (reg:CC 100))]
781 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
783 (set (match_dup 0) (minus:SI (match_dup 2)
784 (geu:SI (reg:CC 100) (const_int 0))))]
786 [(set_attr "length" "2")])
788 ;; We can also do GEU and LTU directly, but these operate after a compare.
789 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
792 (define_insn "*sltu_insn"
793 [(set (match_operand:SI 0 "register_operand" "=r")
794 (ltu:SI (reg:CC 100) (const_int 0)))]
797 [(set_attr "type" "ialuX")])
799 (define_insn "*neg_sltu_insn"
800 [(set (match_operand:SI 0 "register_operand" "=r")
801 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
804 [(set_attr "type" "ialuX")])
806 ;; ??? Combine should canonicalize these next two to the same pattern.
807 (define_insn "*neg_sltu_minus_x"
808 [(set (match_operand:SI 0 "register_operand" "=r")
809 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
810 (match_operand:SI 1 "arith_operand" "rI")))]
813 [(set_attr "type" "ialuX")])
815 (define_insn "*neg_sltu_plus_x"
816 [(set (match_operand:SI 0 "register_operand" "=r")
817 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
818 (match_operand:SI 1 "arith_operand" "rI"))))]
821 [(set_attr "type" "ialuX")])
823 (define_insn "*sgeu_insn"
824 [(set (match_operand:SI 0 "register_operand" "=r")
825 (geu:SI (reg:CC 100) (const_int 0)))]
828 [(set_attr "type" "ialuX")])
830 (define_insn "*neg_sgeu_insn"
831 [(set (match_operand:SI 0 "register_operand" "=r")
832 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
835 [(set_attr "type" "ialuX")])
837 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
838 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
841 (define_insn "*sltu_plus_x"
842 [(set (match_operand:SI 0 "register_operand" "=r")
843 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
844 (match_operand:SI 1 "arith_operand" "rI")))]
847 [(set_attr "type" "ialuX")])
849 (define_insn "*sltu_plus_x_plus_y"
850 [(set (match_operand:SI 0 "register_operand" "=r")
851 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
852 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
853 (match_operand:SI 2 "arith_operand" "rI"))))]
856 [(set_attr "type" "ialuX")])
858 (define_insn "*x_minus_sltu"
859 [(set (match_operand:SI 0 "register_operand" "=r")
860 (minus:SI (match_operand:SI 1 "register_operand" "r")
861 (ltu:SI (reg:CC 100) (const_int 0))))]
864 [(set_attr "type" "ialuX")])
866 ;; ??? Combine should canonicalize these next two to the same pattern.
867 (define_insn "*x_minus_y_minus_sltu"
868 [(set (match_operand:SI 0 "register_operand" "=r")
869 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
870 (match_operand:SI 2 "arith_operand" "rI"))
871 (ltu:SI (reg:CC 100) (const_int 0))))]
874 [(set_attr "type" "ialuX")])
876 (define_insn "*x_minus_sltu_plus_y"
877 [(set (match_operand:SI 0 "register_operand" "=r")
878 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
879 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
880 (match_operand:SI 2 "arith_operand" "rI"))))]
883 [(set_attr "type" "ialuX")])
885 (define_insn "*sgeu_plus_x"
886 [(set (match_operand:SI 0 "register_operand" "=r")
887 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
888 (match_operand:SI 1 "register_operand" "r")))]
891 [(set_attr "type" "ialuX")])
893 (define_insn "*x_minus_sgeu"
894 [(set (match_operand:SI 0 "register_operand" "=r")
895 (minus:SI (match_operand:SI 1 "register_operand" "r")
896 (geu:SI (reg:CC 100) (const_int 0))))]
899 [(set_attr "type" "ialuX")])
902 [(set (match_operand:SI 0 "register_operand" "")
903 (match_operator:SI 2 "noov_compare_operator"
904 [(match_operand 1 "icc_or_fcc_register_operand" "")
907 && REGNO (operands[1]) == SPARC_ICC_REG
908 && (GET_MODE (operands[1]) == CCXmode
909 /* 32-bit LTU/GEU are better implemented using addx/subx. */
910 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
911 [(set (match_dup 0) (const_int 0))
913 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
919 ;; These control RTL generation for conditional jump insns
921 (define_expand "cbranchcc4"
923 (if_then_else (match_operator 0 "comparison_operator"
924 [(match_operand 1 "compare_operand" "")
925 (match_operand 2 "const_zero_operand" "")])
926 (label_ref (match_operand 3 "" ""))
931 (define_expand "cbranchsi4"
932 [(use (match_operator 0 "comparison_operator"
933 [(match_operand:SI 1 "compare_operand" "")
934 (match_operand:SI 2 "arith_operand" "")]))
935 (use (match_operand 3 ""))]
938 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
939 operands[1] = force_reg (SImode, operands[1]);
940 emit_conditional_branch_insn (operands);
944 (define_expand "cbranchdi4"
945 [(use (match_operator 0 "comparison_operator"
946 [(match_operand:DI 1 "compare_operand" "")
947 (match_operand:DI 2 "arith_operand" "")]))
948 (use (match_operand 3 ""))]
951 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
952 operands[1] = force_reg (DImode, operands[1]);
953 emit_conditional_branch_insn (operands);
957 (define_expand "cbranch<F:mode>4"
958 [(use (match_operator 0 "comparison_operator"
959 [(match_operand:F 1 "register_operand" "")
960 (match_operand:F 2 "register_operand" "")]))
961 (use (match_operand 3 ""))]
963 { emit_conditional_branch_insn (operands); DONE; })
966 ;; Now match both normal and inverted jump.
968 ;; XXX fpcmp nop braindamage
969 (define_insn "*normal_branch"
971 (if_then_else (match_operator 0 "noov_compare_operator"
972 [(reg 100) (const_int 0)])
973 (label_ref (match_operand 1 "" ""))
977 return output_cbranch (operands[0], operands[1], 1, 0,
978 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
981 [(set_attr "type" "branch")
982 (set_attr "branch_type" "icc")])
984 ;; XXX fpcmp nop braindamage
985 (define_insn "*inverted_branch"
987 (if_then_else (match_operator 0 "noov_compare_operator"
988 [(reg 100) (const_int 0)])
990 (label_ref (match_operand 1 "" ""))))]
993 return output_cbranch (operands[0], operands[1], 1, 1,
994 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
997 [(set_attr "type" "branch")
998 (set_attr "branch_type" "icc")])
1000 ;; XXX fpcmp nop braindamage
1001 (define_insn "*normal_fp_branch"
1003 (if_then_else (match_operator 1 "comparison_operator"
1004 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1006 (label_ref (match_operand 2 "" ""))
1010 return output_cbranch (operands[1], operands[2], 2, 0,
1011 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1014 [(set_attr "type" "branch")
1015 (set_attr "branch_type" "fcc")])
1017 ;; XXX fpcmp nop braindamage
1018 (define_insn "*inverted_fp_branch"
1020 (if_then_else (match_operator 1 "comparison_operator"
1021 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1024 (label_ref (match_operand 2 "" ""))))]
1027 return output_cbranch (operands[1], operands[2], 2, 1,
1028 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1031 [(set_attr "type" "branch")
1032 (set_attr "branch_type" "fcc")])
1034 ;; XXX fpcmp nop braindamage
1035 (define_insn "*normal_fpe_branch"
1037 (if_then_else (match_operator 1 "comparison_operator"
1038 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1040 (label_ref (match_operand 2 "" ""))
1044 return output_cbranch (operands[1], operands[2], 2, 0,
1045 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1048 [(set_attr "type" "branch")
1049 (set_attr "branch_type" "fcc")])
1051 ;; XXX fpcmp nop braindamage
1052 (define_insn "*inverted_fpe_branch"
1054 (if_then_else (match_operator 1 "comparison_operator"
1055 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1058 (label_ref (match_operand 2 "" ""))))]
1061 return output_cbranch (operands[1], operands[2], 2, 1,
1062 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1065 [(set_attr "type" "branch")
1066 (set_attr "branch_type" "fcc")])
1068 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1069 ;; in the architecture.
1071 ;; There are no 32 bit brreg insns.
1074 (define_insn "*normal_int_branch_sp64"
1076 (if_then_else (match_operator 0 "v9_register_compare_operator"
1077 [(match_operand:DI 1 "register_operand" "r")
1079 (label_ref (match_operand 2 "" ""))
1083 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1084 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1087 [(set_attr "type" "branch")
1088 (set_attr "branch_type" "reg")])
1091 (define_insn "*inverted_int_branch_sp64"
1093 (if_then_else (match_operator 0 "v9_register_compare_operator"
1094 [(match_operand:DI 1 "register_operand" "r")
1097 (label_ref (match_operand 2 "" ""))))]
1100 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1101 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1104 [(set_attr "type" "branch")
1105 (set_attr "branch_type" "reg")])
1108 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1109 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1110 ;; that adds the PC value at the call point to operand 0.
1112 (define_insn "load_pcrel_sym<P:mode>"
1113 [(set (match_operand:P 0 "register_operand" "=r")
1114 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1115 (match_operand:P 2 "call_address_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1116 (clobber (reg:P 15))]
1119 if (flag_delayed_branch)
1120 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1122 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1124 [(set (attr "type") (const_string "multi"))
1125 (set (attr "length")
1126 (if_then_else (eq_attr "delayed_branch" "true")
1131 ;; Integer move instructions
1133 (define_expand "movqi"
1134 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1135 (match_operand:QI 1 "general_operand" ""))]
1138 if (sparc_expand_move (QImode, operands))
1142 (define_insn "*movqi_insn"
1143 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1144 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1145 "(register_operand (operands[0], QImode)
1146 || register_or_zero_operand (operands[1], QImode))"
1151 [(set_attr "type" "*,load,store")
1152 (set_attr "us3load_type" "*,3cycle,*")])
1154 (define_expand "movhi"
1155 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1156 (match_operand:HI 1 "general_operand" ""))]
1159 if (sparc_expand_move (HImode, operands))
1163 (define_insn "*movhi_insn"
1164 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1165 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1166 "(register_operand (operands[0], HImode)
1167 || register_or_zero_operand (operands[1], HImode))"
1170 sethi\t%%hi(%a1), %0
1173 [(set_attr "type" "*,*,load,store")
1174 (set_attr "us3load_type" "*,*,3cycle,*")])
1176 ;; We always work with constants here.
1177 (define_insn "*movhi_lo_sum"
1178 [(set (match_operand:HI 0 "register_operand" "=r")
1179 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1180 (match_operand:HI 2 "small_int_operand" "I")))]
1184 (define_expand "movsi"
1185 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1186 (match_operand:SI 1 "general_operand" ""))]
1189 if (sparc_expand_move (SImode, operands))
1193 (define_insn "*movsi_insn"
1194 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d")
1195 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,f,m,f,J"))]
1196 "(register_operand (operands[0], SImode)
1197 || register_or_zero_operand (operands[1], SImode))"
1200 sethi\t%%hi(%a1), %0
1207 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")])
1209 (define_insn "*movsi_lo_sum"
1210 [(set (match_operand:SI 0 "register_operand" "=r")
1211 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1212 (match_operand:SI 2 "immediate_operand" "in")))]
1214 "or\t%1, %%lo(%a2), %0")
1216 (define_insn "*movsi_high"
1217 [(set (match_operand:SI 0 "register_operand" "=r")
1218 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1220 "sethi\t%%hi(%a1), %0")
1222 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1223 ;; so that CSE won't optimize the address computation away.
1224 (define_insn "movsi_lo_sum_pic"
1225 [(set (match_operand:SI 0 "register_operand" "=r")
1226 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1227 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1230 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1231 return "xor\t%1, %%gdop_lox10(%a2), %0";
1233 return "or\t%1, %%lo(%a2), %0";
1237 (define_insn "movsi_high_pic"
1238 [(set (match_operand:SI 0 "register_operand" "=r")
1239 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1240 "flag_pic && check_pic (1)"
1242 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1243 return "sethi\t%%gdop_hix22(%a1), %0";
1245 return "sethi\t%%hi(%a1), %0";
1249 (define_insn "movsi_pic_gotdata_op"
1250 [(set (match_operand:SI 0 "register_operand" "=r")
1251 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1252 (match_operand:SI 2 "register_operand" "r")
1253 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1254 "flag_pic && check_pic (1)"
1256 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1257 return "ld\t[%1 + %2], %0, %%gdop(%a3)";
1259 return "ld\t[%1 + %2], %0";
1262 [(set_attr "type" "load")])
1264 (define_expand "movsi_pic_label_ref"
1265 [(set (match_dup 3) (high:SI
1266 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1267 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1268 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1269 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1270 (set (match_operand:SI 0 "register_operand" "=r")
1271 (minus:SI (match_dup 5) (match_dup 4)))]
1274 crtl->uses_pic_offset_table = 1;
1275 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1276 if (!can_create_pseudo_p ())
1278 operands[3] = operands[0];
1279 operands[4] = operands[0];
1283 operands[3] = gen_reg_rtx (SImode);
1284 operands[4] = gen_reg_rtx (SImode);
1286 operands[5] = pic_offset_table_rtx;
1289 (define_insn "*movsi_high_pic_label_ref"
1290 [(set (match_operand:SI 0 "register_operand" "=r")
1292 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1293 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1295 "sethi\t%%hi(%a2-(%a1-.)), %0")
1297 (define_insn "*movsi_lo_sum_pic_label_ref"
1298 [(set (match_operand:SI 0 "register_operand" "=r")
1299 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1300 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1301 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1303 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1305 ;; Set up the PIC register for VxWorks.
1307 (define_expand "vxworks_load_got"
1309 (high:SI (match_dup 1)))
1311 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1313 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1314 "TARGET_VXWORKS_RTP"
1316 operands[0] = pic_offset_table_rtx;
1317 operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1318 operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1321 (define_expand "movdi"
1322 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1323 (match_operand:DI 1 "general_operand" ""))]
1326 if (sparc_expand_move (DImode, operands))
1330 ;; Be careful, fmovd does not exist when !v9.
1331 ;; We match MEM moves directly when we have correct even
1332 ;; numbered registers, but fall into splits otherwise.
1333 ;; The constraint ordering here is really important to
1334 ;; avoid insane problems in reload, especially for patterns
1337 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1338 ;; (const_int -5016)))
1342 (define_insn "*movdi_insn_sp32"
1343 [(set (match_operand:DI 0 "nonimmediate_operand"
1344 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1345 (match_operand:DI 1 "input_operand"
1346 " J,U,T,r,o,i,r, f, T, o, f, f"))]
1348 && (register_operand (operands[0], DImode)
1349 || register_or_zero_operand (operands[1], DImode))"
1363 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1364 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1366 (define_insn "*movdi_insn_sp32_v9"
1367 [(set (match_operand:DI 0 "nonimmediate_operand"
1368 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1369 (match_operand:DI 1 "input_operand"
1370 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1373 && (register_operand (operands[0], DImode)
1374 || register_or_zero_operand (operands[1], DImode))"
1391 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
1392 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
1393 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
1395 (define_insn "*movdi_insn_sp64"
1396 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b")
1397 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,e,W,e,J"))]
1399 && (register_operand (operands[0], DImode)
1400 || register_or_zero_operand (operands[1], DImode))"
1403 sethi\t%%hi(%a1), %0
1410 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")
1411 (set_attr "fptype" "*,*,*,*,double,*,*,double")])
1413 (define_expand "movdi_pic_label_ref"
1414 [(set (match_dup 3) (high:DI
1415 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1416 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1417 (set (match_dup 4) (lo_sum:DI (match_dup 3)
1418 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1419 (set (match_operand:DI 0 "register_operand" "=r")
1420 (minus:DI (match_dup 5) (match_dup 4)))]
1421 "TARGET_ARCH64 && flag_pic"
1423 crtl->uses_pic_offset_table = 1;
1424 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1425 if (!can_create_pseudo_p ())
1427 operands[3] = operands[0];
1428 operands[4] = operands[0];
1432 operands[3] = gen_reg_rtx (DImode);
1433 operands[4] = gen_reg_rtx (DImode);
1435 operands[5] = pic_offset_table_rtx;
1438 (define_insn "*movdi_high_pic_label_ref"
1439 [(set (match_operand:DI 0 "register_operand" "=r")
1441 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1442 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1443 "TARGET_ARCH64 && flag_pic"
1444 "sethi\t%%hi(%a2-(%a1-.)), %0")
1446 (define_insn "*movdi_lo_sum_pic_label_ref"
1447 [(set (match_operand:DI 0 "register_operand" "=r")
1448 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1449 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
1450 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1451 "TARGET_ARCH64 && flag_pic"
1452 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1454 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
1455 ;; in sparc.c to see what is going on here... PIC stuff comes first.
1457 (define_insn "movdi_lo_sum_pic"
1458 [(set (match_operand:DI 0 "register_operand" "=r")
1459 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1460 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1461 "TARGET_ARCH64 && flag_pic"
1463 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1464 return "xor\t%1, %%gdop_lox10(%a2), %0";
1466 return "or\t%1, %%lo(%a2), %0";
1470 (define_insn "movdi_high_pic"
1471 [(set (match_operand:DI 0 "register_operand" "=r")
1472 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1473 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1475 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1476 return "sethi\t%%gdop_hix22(%a1), %0";
1478 return "sethi\t%%hi(%a1), %0";
1482 (define_insn "movdi_pic_gotdata_op"
1483 [(set (match_operand:DI 0 "register_operand" "=r")
1484 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1485 (match_operand:DI 2 "register_operand" "r")
1486 (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1487 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1489 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1490 return "ldx\t[%1 + %2], %0, %%gdop(%a3)";
1492 return "ldx\t[%1 + %2], %0";
1495 [(set_attr "type" "load")])
1497 (define_insn "*sethi_di_medlow_embmedany_pic"
1498 [(set (match_operand:DI 0 "register_operand" "=r")
1499 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
1500 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
1501 "sethi\t%%hi(%a1), %0")
1503 (define_insn "*sethi_di_medlow"
1504 [(set (match_operand:DI 0 "register_operand" "=r")
1505 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
1506 "TARGET_CM_MEDLOW && check_pic (1)"
1507 "sethi\t%%hi(%a1), %0")
1509 (define_insn "*losum_di_medlow"
1510 [(set (match_operand:DI 0 "register_operand" "=r")
1511 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1512 (match_operand:DI 2 "symbolic_operand" "")))]
1514 "or\t%1, %%lo(%a2), %0")
1516 (define_insn "seth44"
1517 [(set (match_operand:DI 0 "register_operand" "=r")
1518 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
1520 "sethi\t%%h44(%a1), %0")
1522 (define_insn "setm44"
1523 [(set (match_operand:DI 0 "register_operand" "=r")
1524 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1525 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
1527 "or\t%1, %%m44(%a2), %0")
1529 (define_insn "setl44"
1530 [(set (match_operand:DI 0 "register_operand" "=r")
1531 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1532 (match_operand:DI 2 "symbolic_operand" "")))]
1534 "or\t%1, %%l44(%a2), %0")
1536 (define_insn "sethh"
1537 [(set (match_operand:DI 0 "register_operand" "=r")
1538 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
1540 "sethi\t%%hh(%a1), %0")
1542 (define_insn "setlm"
1543 [(set (match_operand:DI 0 "register_operand" "=r")
1544 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
1546 "sethi\t%%lm(%a1), %0")
1548 (define_insn "sethm"
1549 [(set (match_operand:DI 0 "register_operand" "=r")
1550 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1551 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
1553 "or\t%1, %%hm(%a2), %0")
1555 (define_insn "setlo"
1556 [(set (match_operand:DI 0 "register_operand" "=r")
1557 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1558 (match_operand:DI 2 "symbolic_operand" "")))]
1560 "or\t%1, %%lo(%a2), %0")
1562 (define_insn "embmedany_sethi"
1563 [(set (match_operand:DI 0 "register_operand" "=r")
1564 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
1565 "TARGET_CM_EMBMEDANY && check_pic (1)"
1566 "sethi\t%%hi(%a1), %0")
1568 (define_insn "embmedany_losum"
1569 [(set (match_operand:DI 0 "register_operand" "=r")
1570 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1571 (match_operand:DI 2 "data_segment_operand" "")))]
1572 "TARGET_CM_EMBMEDANY"
1573 "add\t%1, %%lo(%a2), %0")
1575 (define_insn "embmedany_brsum"
1576 [(set (match_operand:DI 0 "register_operand" "=r")
1577 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
1578 "TARGET_CM_EMBMEDANY"
1581 (define_insn "embmedany_textuhi"
1582 [(set (match_operand:DI 0 "register_operand" "=r")
1583 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
1584 "TARGET_CM_EMBMEDANY && check_pic (1)"
1585 "sethi\t%%uhi(%a1), %0")
1587 (define_insn "embmedany_texthi"
1588 [(set (match_operand:DI 0 "register_operand" "=r")
1589 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
1590 "TARGET_CM_EMBMEDANY && check_pic (1)"
1591 "sethi\t%%hi(%a1), %0")
1593 (define_insn "embmedany_textulo"
1594 [(set (match_operand:DI 0 "register_operand" "=r")
1595 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1596 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
1597 "TARGET_CM_EMBMEDANY"
1598 "or\t%1, %%ulo(%a2), %0")
1600 (define_insn "embmedany_textlo"
1601 [(set (match_operand:DI 0 "register_operand" "=r")
1602 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1603 (match_operand:DI 2 "text_segment_operand" "")))]
1604 "TARGET_CM_EMBMEDANY"
1605 "or\t%1, %%lo(%a2), %0")
1607 ;; Now some patterns to help reload out a bit.
1608 (define_expand "reload_indi"
1609 [(parallel [(match_operand:DI 0 "register_operand" "=r")
1610 (match_operand:DI 1 "immediate_operand" "")
1611 (match_operand:TI 2 "register_operand" "=&r")])]
1613 || TARGET_CM_EMBMEDANY)
1616 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1620 (define_expand "reload_outdi"
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 ;; Split up putting CONSTs and REGs into DI regs when !arch64
1634 [(set (match_operand:DI 0 "register_operand" "")
1635 (match_operand:DI 1 "const_int_operand" ""))]
1636 "! TARGET_ARCH64 && reload_completed"
1637 [(clobber (const_int 0))]
1639 #if HOST_BITS_PER_WIDE_INT == 32
1640 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1641 (INTVAL (operands[1]) < 0) ?
1644 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1647 unsigned int low, high;
1649 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
1650 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
1651 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
1653 /* Slick... but this trick loses if this subreg constant part
1654 can be done in one insn. */
1656 && ! SPARC_SETHI32_P (high)
1657 && ! SPARC_SIMM13_P (high))
1658 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1659 gen_highpart (SImode, operands[0])));
1661 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
1667 [(set (match_operand:DI 0 "register_operand" "")
1668 (match_operand:DI 1 "const_double_operand" ""))]
1672 && ((GET_CODE (operands[0]) == REG
1673 && REGNO (operands[0]) < 32)
1674 || (GET_CODE (operands[0]) == SUBREG
1675 && GET_CODE (SUBREG_REG (operands[0])) == REG
1676 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1677 [(clobber (const_int 0))]
1679 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1680 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
1682 /* Slick... but this trick loses if this subreg constant part
1683 can be done in one insn. */
1684 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
1685 && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
1686 && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
1688 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1689 gen_highpart (SImode, operands[0])));
1693 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1694 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
1700 [(set (match_operand:DI 0 "register_operand" "")
1701 (match_operand:DI 1 "register_operand" ""))]
1705 && ((GET_CODE (operands[0]) == REG
1706 && REGNO (operands[0]) < 32)
1707 || (GET_CODE (operands[0]) == SUBREG
1708 && GET_CODE (SUBREG_REG (operands[0])) == REG
1709 && REGNO (SUBREG_REG (operands[0])) < 32))))"
1710 [(clobber (const_int 0))]
1712 rtx set_dest = operands[0];
1713 rtx set_src = operands[1];
1717 dest1 = gen_highpart (SImode, set_dest);
1718 dest2 = gen_lowpart (SImode, set_dest);
1719 src1 = gen_highpart (SImode, set_src);
1720 src2 = gen_lowpart (SImode, set_src);
1722 /* Now emit using the real source and destination we found, swapping
1723 the order if we detect overlap. */
1724 if (reg_overlap_mentioned_p (dest1, src2))
1726 emit_insn (gen_movsi (dest2, src2));
1727 emit_insn (gen_movsi (dest1, src1));
1731 emit_insn (gen_movsi (dest1, src1));
1732 emit_insn (gen_movsi (dest2, src2));
1737 ;; Now handle the cases of memory moves from/to non-even
1738 ;; DI mode register pairs.
1740 [(set (match_operand:DI 0 "register_operand" "")
1741 (match_operand:DI 1 "memory_operand" ""))]
1744 && sparc_splitdi_legitimate (operands[0], operands[1]))"
1745 [(clobber (const_int 0))]
1747 rtx word0 = adjust_address (operands[1], SImode, 0);
1748 rtx word1 = adjust_address (operands[1], SImode, 4);
1749 rtx high_part = gen_highpart (SImode, operands[0]);
1750 rtx low_part = gen_lowpart (SImode, operands[0]);
1752 if (reg_overlap_mentioned_p (high_part, word1))
1754 emit_insn (gen_movsi (low_part, word1));
1755 emit_insn (gen_movsi (high_part, word0));
1759 emit_insn (gen_movsi (high_part, word0));
1760 emit_insn (gen_movsi (low_part, word1));
1766 [(set (match_operand:DI 0 "memory_operand" "")
1767 (match_operand:DI 1 "register_operand" ""))]
1770 && sparc_splitdi_legitimate (operands[1], operands[0]))"
1771 [(clobber (const_int 0))]
1773 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
1774 gen_highpart (SImode, operands[1])));
1775 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
1776 gen_lowpart (SImode, operands[1])));
1781 [(set (match_operand:DI 0 "memory_operand" "")
1782 (match_operand:DI 1 "const_zero_operand" ""))]
1786 && ! mem_min_alignment (operands[0], 8)))
1787 && offsettable_memref_p (operands[0])"
1788 [(clobber (const_int 0))]
1790 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
1791 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
1796 ;; Floating point and vector move instructions
1798 ;; Yes, you guessed it right, the former movsf expander.
1799 (define_expand "mov<V32:mode>"
1800 [(set (match_operand:V32 0 "nonimmediate_operand" "")
1801 (match_operand:V32 1 "general_operand" ""))]
1802 "<V32:MODE>mode == SFmode || TARGET_VIS"
1804 if (sparc_expand_move (<V32:MODE>mode, operands))
1808 (define_insn "*movsf_insn"
1809 [(set (match_operand:V32 0 "nonimmediate_operand" "=d,f,*r,*r,*r,f,*r,m,m")
1810 (match_operand:V32 1 "input_operand" "GY,f,*rRY,Q,S,m,m,f,*rGY"))]
1812 && (register_operand (operands[0], <V32:MODE>mode)
1813 || register_or_zero_operand (operands[1], <V32:MODE>mode))"
1815 if (GET_CODE (operands[1]) == CONST_DOUBLE
1816 && (which_alternative == 2
1817 || which_alternative == 3
1818 || which_alternative == 4))
1823 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1824 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1825 operands[1] = GEN_INT (i);
1828 switch (which_alternative)
1831 return "fzeros\t%0";
1833 return "fmovs\t%1, %0";
1835 return "mov\t%1, %0";
1837 return "sethi\t%%hi(%a1), %0";
1842 return "ld\t%1, %0";
1845 return "st\t%r1, %0";
1850 [(set_attr "type" "fga,fpmove,*,*,*,fpload,load,fpstore,store")])
1852 ;; Exactly the same as above, except that all `f' cases are deleted.
1853 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1856 (define_insn "*movsf_insn_no_fpu"
1857 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
1858 (match_operand:SF 1 "input_operand" "rR,Q,S,m,rG"))]
1860 && (register_operand (operands[0], SFmode)
1861 || register_or_zero_operand (operands[1], SFmode))"
1863 if (GET_CODE (operands[1]) == CONST_DOUBLE
1864 && (which_alternative == 0
1865 || which_alternative == 1
1866 || which_alternative == 2))
1871 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1872 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1873 operands[1] = GEN_INT (i);
1876 switch (which_alternative)
1879 return "mov\t%1, %0";
1881 return "sethi\t%%hi(%a1), %0";
1885 return "ld\t%1, %0";
1887 return "st\t%r1, %0";
1892 [(set_attr "type" "*,*,*,load,store")])
1894 ;; The following 3 patterns build SFmode constants in integer registers.
1896 (define_insn "*movsf_lo_sum"
1897 [(set (match_operand:SF 0 "register_operand" "=r")
1898 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
1899 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
1905 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
1906 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1907 operands[2] = GEN_INT (i);
1908 return "or\t%1, %%lo(%a2), %0";
1911 (define_insn "*movsf_high"
1912 [(set (match_operand:SF 0 "register_operand" "=r")
1913 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
1919 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1920 REAL_VALUE_TO_TARGET_SINGLE (r, i);
1921 operands[1] = GEN_INT (i);
1922 return "sethi\t%%hi(%1), %0";
1926 [(set (match_operand:SF 0 "register_operand" "")
1927 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
1928 "REG_P (operands[0]) && REGNO (operands[0]) < 32"
1929 [(set (match_dup 0) (high:SF (match_dup 1)))
1930 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
1932 ;; Yes, you again guessed it right, the former movdf expander.
1933 (define_expand "mov<V64:mode>"
1934 [(set (match_operand:V64 0 "nonimmediate_operand" "")
1935 (match_operand:V64 1 "general_operand" ""))]
1936 "<V64:MODE>mode == DFmode || TARGET_VIS"
1938 if (sparc_expand_move (<V64:MODE>mode, operands))
1942 ;; Be careful, fmovd does not exist when !v9.
1943 (define_insn "*movdf_insn_sp32"
1944 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
1945 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
1948 && (register_operand (operands[0], DFmode)
1949 || register_or_zero_operand (operands[1], DFmode))"
1961 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
1962 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
1964 (define_insn "*movdf_insn_sp32_no_fpu"
1965 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
1966 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
1969 && (register_operand (operands[0], DFmode)
1970 || register_or_zero_operand (operands[1], DFmode))"
1977 [(set_attr "type" "load,store,*,*,*")
1978 (set_attr "length" "*,*,2,2,2")])
1980 ;; We have available v9 double floats but not 64-bit integer registers.
1981 (define_insn "*movdf_insn_sp32_v9"
1982 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o")
1983 (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYDF,*rGYf"))]
1987 && (register_operand (operands[0], <V64:MODE>mode)
1988 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2000 [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
2001 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2002 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2004 (define_insn "*movdf_insn_sp32_v9_no_fpu"
2005 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2006 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2010 && (register_operand (operands[0], DFmode)
2011 || register_or_zero_operand (operands[1], DFmode))"
2018 [(set_attr "type" "load,store,store,*,*")
2019 (set_attr "length" "*,*,*,2,2")])
2021 ;; We have available both v9 double floats and 64-bit integer registers.
2022 (define_insn "*movdf_insn_sp64"
2023 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r")
2024 (match_operand:V64 1 "input_operand" "GY,e,W#F,e,*rGY,m,*rGY,DF"))]
2027 && (register_operand (operands[0], <V64:MODE>mode)
2028 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2038 [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
2039 (set_attr "length" "*,*,*,*,*,*,*,2")
2040 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
2042 (define_insn "*movdf_insn_sp64_no_fpu"
2043 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2044 (match_operand:DF 1 "input_operand" "r,m,rG"))]
2047 && (register_operand (operands[0], DFmode)
2048 || register_or_zero_operand (operands[1], DFmode))"
2053 [(set_attr "type" "*,load,store")])
2055 ;; This pattern builds V64mode constants in integer registers.
2057 [(set (match_operand:V64 0 "register_operand" "")
2058 (match_operand:V64 1 "const_double_or_vector_operand" ""))]
2060 && (GET_CODE (operands[0]) == REG
2061 && REGNO (operands[0]) < 32)
2062 && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2063 && reload_completed"
2064 [(clobber (const_int 0))]
2066 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2070 #if HOST_BITS_PER_WIDE_INT == 32
2073 enum machine_mode mode = GET_MODE (operands[1]);
2074 rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2075 emit_insn (gen_movdi (operands[0], tem));
2080 enum machine_mode mode = GET_MODE (operands[1]);
2081 rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2082 rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2084 gcc_assert (GET_CODE (hi) == CONST_INT);
2085 gcc_assert (GET_CODE (lo) == CONST_INT);
2087 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2089 /* Slick... but this trick loses if this subreg constant part
2090 can be done in one insn. */
2092 && ! SPARC_SETHI32_P (INTVAL (hi))
2093 && ! SPARC_SIMM13_P (INTVAL (hi)))
2095 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2096 gen_highpart (SImode, operands[0])));
2100 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2106 ;; Ok, now the splits to handle all the multi insn and
2107 ;; mis-aligned memory address cases.
2108 ;; In these splits please take note that we must be
2109 ;; careful when V9 but not ARCH64 because the integer
2110 ;; register DFmode cases must be handled.
2112 [(set (match_operand:V64 0 "register_operand" "")
2113 (match_operand:V64 1 "register_operand" ""))]
2116 && ((GET_CODE (operands[0]) == REG
2117 && REGNO (operands[0]) < 32)
2118 || (GET_CODE (operands[0]) == SUBREG
2119 && GET_CODE (SUBREG_REG (operands[0])) == REG
2120 && REGNO (SUBREG_REG (operands[0])) < 32))))
2121 && reload_completed"
2122 [(clobber (const_int 0))]
2124 rtx set_dest = operands[0];
2125 rtx set_src = operands[1];
2128 enum machine_mode half_mode;
2130 /* We can be expanded for DFmode or integral vector modes. */
2131 if (<V64:MODE>mode == DFmode)
2136 dest1 = gen_highpart (half_mode, set_dest);
2137 dest2 = gen_lowpart (half_mode, set_dest);
2138 src1 = gen_highpart (half_mode, set_src);
2139 src2 = gen_lowpart (half_mode, set_src);
2141 /* Now emit using the real source and destination we found, swapping
2142 the order if we detect overlap. */
2143 if (reg_overlap_mentioned_p (dest1, src2))
2145 emit_move_insn_1 (dest2, src2);
2146 emit_move_insn_1 (dest1, src1);
2150 emit_move_insn_1 (dest1, src1);
2151 emit_move_insn_1 (dest2, src2);
2157 [(set (match_operand:V64 0 "register_operand" "")
2158 (match_operand:V64 1 "memory_operand" ""))]
2161 && (((REGNO (operands[0]) % 2) != 0)
2162 || ! mem_min_alignment (operands[1], 8))
2163 && offsettable_memref_p (operands[1])"
2164 [(clobber (const_int 0))]
2166 enum machine_mode half_mode;
2169 /* We can be expanded for DFmode or integral vector modes. */
2170 if (<V64:MODE>mode == DFmode)
2175 word0 = adjust_address (operands[1], half_mode, 0);
2176 word1 = adjust_address (operands[1], half_mode, 4);
2178 if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
2180 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2181 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2185 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2186 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2192 [(set (match_operand:V64 0 "memory_operand" "")
2193 (match_operand:V64 1 "register_operand" ""))]
2196 && (((REGNO (operands[1]) % 2) != 0)
2197 || ! mem_min_alignment (operands[0], 8))
2198 && offsettable_memref_p (operands[0])"
2199 [(clobber (const_int 0))]
2201 enum machine_mode half_mode;
2204 /* We can be expanded for DFmode or integral vector modes. */
2205 if (<V64:MODE>mode == DFmode)
2210 word0 = adjust_address (operands[0], half_mode, 0);
2211 word1 = adjust_address (operands[0], half_mode, 4);
2213 emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
2214 emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
2219 [(set (match_operand:V64 0 "memory_operand" "")
2220 (match_operand:V64 1 "const_zero_operand" ""))]
2224 && ! mem_min_alignment (operands[0], 8)))
2225 && offsettable_memref_p (operands[0])"
2226 [(clobber (const_int 0))]
2228 enum machine_mode half_mode;
2231 /* We can be expanded for DFmode or integral vector modes. */
2232 if (<V64:MODE>mode == DFmode)
2237 dest1 = adjust_address (operands[0], half_mode, 0);
2238 dest2 = adjust_address (operands[0], half_mode, 4);
2240 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2241 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2246 [(set (match_operand:V64 0 "register_operand" "")
2247 (match_operand:V64 1 "const_zero_operand" ""))]
2250 && ((GET_CODE (operands[0]) == REG
2251 && REGNO (operands[0]) < 32)
2252 || (GET_CODE (operands[0]) == SUBREG
2253 && GET_CODE (SUBREG_REG (operands[0])) == REG
2254 && REGNO (SUBREG_REG (operands[0])) < 32))"
2255 [(clobber (const_int 0))]
2257 enum machine_mode half_mode;
2258 rtx set_dest = operands[0];
2261 /* We can be expanded for DFmode or integral vector modes. */
2262 if (<V64:MODE>mode == DFmode)
2267 dest1 = gen_highpart (half_mode, set_dest);
2268 dest2 = gen_lowpart (half_mode, set_dest);
2269 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2270 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2274 (define_expand "movtf"
2275 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2276 (match_operand:TF 1 "general_operand" ""))]
2279 if (sparc_expand_move (TFmode, operands))
2283 (define_insn "*movtf_insn_sp32"
2284 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2285 (match_operand:TF 1 "input_operand" "G,oe,GeUr,o,roG"))]
2288 && (register_operand (operands[0], TFmode)
2289 || register_or_zero_operand (operands[1], TFmode))"
2291 [(set_attr "length" "4")])
2293 ;; Exactly the same as above, except that all `e' cases are deleted.
2294 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2297 (define_insn "*movtf_insn_sp32_no_fpu"
2298 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2299 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
2302 && (register_operand (operands[0], TFmode)
2303 || register_or_zero_operand (operands[1], TFmode))"
2305 [(set_attr "length" "4")])
2307 (define_insn "*movtf_insn_sp64"
2308 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2309 (match_operand:TF 1 "input_operand" "G,oe,Ger,roG"))]
2312 && ! TARGET_HARD_QUAD
2313 && (register_operand (operands[0], TFmode)
2314 || register_or_zero_operand (operands[1], TFmode))"
2316 [(set_attr "length" "2")])
2318 (define_insn "*movtf_insn_sp64_hq"
2319 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2320 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
2324 && (register_operand (operands[0], TFmode)
2325 || register_or_zero_operand (operands[1], TFmode))"
2333 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2334 (set_attr "length" "2,*,*,*,2,2")])
2336 (define_insn "*movtf_insn_sp64_no_fpu"
2337 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2338 (match_operand:TF 1 "input_operand" "orG,rG"))]
2341 && (register_operand (operands[0], TFmode)
2342 || register_or_zero_operand (operands[1], TFmode))"
2344 [(set_attr "length" "2")])
2346 ;; Now all the splits to handle multi-insn TF mode moves.
2348 [(set (match_operand:TF 0 "register_operand" "")
2349 (match_operand:TF 1 "register_operand" ""))]
2353 && ! TARGET_HARD_QUAD)
2354 || ! fp_register_operand (operands[0], TFmode))"
2355 [(clobber (const_int 0))]
2357 rtx set_dest = operands[0];
2358 rtx set_src = operands[1];
2362 dest1 = gen_df_reg (set_dest, 0);
2363 dest2 = gen_df_reg (set_dest, 1);
2364 src1 = gen_df_reg (set_src, 0);
2365 src2 = gen_df_reg (set_src, 1);
2367 /* Now emit using the real source and destination we found, swapping
2368 the order if we detect overlap. */
2369 if (reg_overlap_mentioned_p (dest1, src2))
2371 emit_insn (gen_movdf (dest2, src2));
2372 emit_insn (gen_movdf (dest1, src1));
2376 emit_insn (gen_movdf (dest1, src1));
2377 emit_insn (gen_movdf (dest2, src2));
2383 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2384 (match_operand:TF 1 "const_zero_operand" ""))]
2386 [(clobber (const_int 0))]
2388 rtx set_dest = operands[0];
2391 switch (GET_CODE (set_dest))
2394 dest1 = gen_df_reg (set_dest, 0);
2395 dest2 = gen_df_reg (set_dest, 1);
2398 dest1 = adjust_address (set_dest, DFmode, 0);
2399 dest2 = adjust_address (set_dest, DFmode, 8);
2405 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2406 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2411 [(set (match_operand:TF 0 "register_operand" "")
2412 (match_operand:TF 1 "memory_operand" ""))]
2414 && offsettable_memref_p (operands[1])
2416 || ! TARGET_HARD_QUAD
2417 || ! fp_register_operand (operands[0], TFmode)))"
2418 [(clobber (const_int 0))]
2420 rtx word0 = adjust_address (operands[1], DFmode, 0);
2421 rtx word1 = adjust_address (operands[1], DFmode, 8);
2422 rtx set_dest, dest1, dest2;
2424 set_dest = operands[0];
2426 dest1 = gen_df_reg (set_dest, 0);
2427 dest2 = gen_df_reg (set_dest, 1);
2429 /* Now output, ordering such that we don't clobber any registers
2430 mentioned in the address. */
2431 if (reg_overlap_mentioned_p (dest1, word1))
2434 emit_insn (gen_movdf (dest2, word1));
2435 emit_insn (gen_movdf (dest1, word0));
2439 emit_insn (gen_movdf (dest1, word0));
2440 emit_insn (gen_movdf (dest2, word1));
2446 [(set (match_operand:TF 0 "memory_operand" "")
2447 (match_operand:TF 1 "register_operand" ""))]
2449 && offsettable_memref_p (operands[0])
2451 || ! TARGET_HARD_QUAD
2452 || ! fp_register_operand (operands[1], TFmode)))"
2453 [(clobber (const_int 0))]
2455 rtx set_src = operands[1];
2457 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2458 gen_df_reg (set_src, 0)));
2459 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2460 gen_df_reg (set_src, 1)));
2465 ;; SPARC-V9 conditional move instructions
2467 ;; We can handle larger constants here for some flavors, but for now we keep
2468 ;; it simple and only allow those constants supported by all flavors.
2469 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2470 ;; 3 contains the constant if one is present, but we handle either for
2471 ;; generality (sparc.c puts a constant in operand 2).
2473 (define_expand "mov<I:mode>cc"
2474 [(set (match_operand:I 0 "register_operand" "")
2475 (if_then_else:I (match_operand 1 "comparison_operator" "")
2476 (match_operand:I 2 "arith10_operand" "")
2477 (match_operand:I 3 "arith10_operand" "")))]
2478 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2480 enum rtx_code code = GET_CODE (operands[1]);
2483 if (GET_MODE (XEXP (operands[1], 0)) == DImode
2487 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2489 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2490 GET_CODE (operands[1]));
2492 if (XEXP (operands[1], 1) == const0_rtx
2493 && GET_CODE (XEXP (operands[1], 0)) == REG
2494 && GET_MODE (XEXP (operands[1], 0)) == DImode
2495 && v9_regcmp_p (code))
2496 cc_reg = XEXP (operands[1], 0);
2498 cc_reg = gen_compare_reg (operands[1]);
2500 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2503 (define_expand "mov<F:mode>cc"
2504 [(set (match_operand:F 0 "register_operand" "")
2505 (if_then_else:F (match_operand 1 "comparison_operator" "")
2506 (match_operand:F 2 "register_operand" "")
2507 (match_operand:F 3 "register_operand" "")))]
2508 "TARGET_V9 && TARGET_FPU"
2510 enum rtx_code code = GET_CODE (operands[1]);
2513 if (GET_MODE (XEXP (operands[1], 0)) == DImode
2517 if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2519 = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2520 GET_CODE (operands[1]));
2522 if (XEXP (operands[1], 1) == const0_rtx
2523 && GET_CODE (XEXP (operands[1], 0)) == REG
2524 && GET_MODE (XEXP (operands[1], 0)) == DImode
2525 && v9_regcmp_p (code))
2526 cc_reg = XEXP (operands[1], 0);
2528 cc_reg = gen_compare_reg (operands[1]);
2530 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2533 ;; Conditional move define_insns
2535 (define_insn "*mov<I:mode>_cc_v9"
2536 [(set (match_operand:I 0 "register_operand" "=r,r")
2537 (if_then_else:I (match_operator 1 "comparison_operator"
2538 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2540 (match_operand:I 3 "arith11_operand" "rL,0")
2541 (match_operand:I 4 "arith11_operand" "0,rL")))]
2542 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2545 mov%c1\t%x2, %4, %0"
2546 [(set_attr "type" "cmove")])
2548 (define_insn "*mov<I:mode>_cc_reg_sp64"
2549 [(set (match_operand:I 0 "register_operand" "=r,r")
2550 (if_then_else:I (match_operator 1 "v9_register_compare_operator"
2551 [(match_operand:DI 2 "register_operand" "r,r")
2553 (match_operand:I 3 "arith10_operand" "rM,0")
2554 (match_operand:I 4 "arith10_operand" "0,rM")))]
2557 movr%D1\t%2, %r3, %0
2558 movr%d1\t%2, %r4, %0"
2559 [(set_attr "type" "cmove")])
2561 (define_insn "*movsf_cc_v9"
2562 [(set (match_operand:SF 0 "register_operand" "=f,f")
2563 (if_then_else:SF (match_operator 1 "comparison_operator"
2564 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2566 (match_operand:SF 3 "register_operand" "f,0")
2567 (match_operand:SF 4 "register_operand" "0,f")))]
2568 "TARGET_V9 && TARGET_FPU"
2570 fmovs%C1\t%x2, %3, %0
2571 fmovs%c1\t%x2, %4, %0"
2572 [(set_attr "type" "fpcmove")])
2574 (define_insn "*movsf_cc_reg_sp64"
2575 [(set (match_operand:SF 0 "register_operand" "=f,f")
2576 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
2577 [(match_operand:DI 2 "register_operand" "r,r")
2579 (match_operand:SF 3 "register_operand" "f,0")
2580 (match_operand:SF 4 "register_operand" "0,f")))]
2581 "TARGET_ARCH64 && TARGET_FPU"
2583 fmovrs%D1\t%2, %3, %0
2584 fmovrs%d1\t%2, %4, %0"
2585 [(set_attr "type" "fpcrmove")])
2587 ;; Named because invoked by movtf_cc_v9
2588 (define_insn "movdf_cc_v9"
2589 [(set (match_operand:DF 0 "register_operand" "=e,e")
2590 (if_then_else:DF (match_operator 1 "comparison_operator"
2591 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2593 (match_operand:DF 3 "register_operand" "e,0")
2594 (match_operand:DF 4 "register_operand" "0,e")))]
2595 "TARGET_V9 && TARGET_FPU"
2597 fmovd%C1\t%x2, %3, %0
2598 fmovd%c1\t%x2, %4, %0"
2599 [(set_attr "type" "fpcmove")
2600 (set_attr "fptype" "double")])
2602 ;; Named because invoked by movtf_cc_reg_sp64
2603 (define_insn "movdf_cc_reg_sp64"
2604 [(set (match_operand:DF 0 "register_operand" "=e,e")
2605 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
2606 [(match_operand:DI 2 "register_operand" "r,r")
2608 (match_operand:DF 3 "register_operand" "e,0")
2609 (match_operand:DF 4 "register_operand" "0,e")))]
2610 "TARGET_ARCH64 && TARGET_FPU"
2612 fmovrd%D1\t%2, %3, %0
2613 fmovrd%d1\t%2, %4, %0"
2614 [(set_attr "type" "fpcrmove")
2615 (set_attr "fptype" "double")])
2617 (define_insn "*movtf_cc_hq_v9"
2618 [(set (match_operand:TF 0 "register_operand" "=e,e")
2619 (if_then_else:TF (match_operator 1 "comparison_operator"
2620 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2622 (match_operand:TF 3 "register_operand" "e,0")
2623 (match_operand:TF 4 "register_operand" "0,e")))]
2624 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2626 fmovq%C1\t%x2, %3, %0
2627 fmovq%c1\t%x2, %4, %0"
2628 [(set_attr "type" "fpcmove")])
2630 (define_insn "*movtf_cc_reg_hq_sp64"
2631 [(set (match_operand:TF 0 "register_operand" "=e,e")
2632 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2633 [(match_operand:DI 2 "register_operand" "r,r")
2635 (match_operand:TF 3 "register_operand" "e,0")
2636 (match_operand:TF 4 "register_operand" "0,e")))]
2637 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
2639 fmovrq%D1\t%2, %3, %0
2640 fmovrq%d1\t%2, %4, %0"
2641 [(set_attr "type" "fpcrmove")])
2643 (define_insn_and_split "*movtf_cc_v9"
2644 [(set (match_operand:TF 0 "register_operand" "=e,e")
2645 (if_then_else:TF (match_operator 1 "comparison_operator"
2646 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2648 (match_operand:TF 3 "register_operand" "e,0")
2649 (match_operand:TF 4 "register_operand" "0,e")))]
2650 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
2652 "&& reload_completed"
2653 [(clobber (const_int 0))]
2655 rtx set_dest = operands[0];
2656 rtx set_srca = operands[3];
2657 rtx set_srcb = operands[4];
2658 int third = rtx_equal_p (set_dest, set_srca);
2660 rtx srca1, srca2, srcb1, srcb2;
2662 dest1 = gen_df_reg (set_dest, 0);
2663 dest2 = gen_df_reg (set_dest, 1);
2664 srca1 = gen_df_reg (set_srca, 0);
2665 srca2 = gen_df_reg (set_srca, 1);
2666 srcb1 = gen_df_reg (set_srcb, 0);
2667 srcb2 = gen_df_reg (set_srcb, 1);
2669 /* Now emit using the real source and destination we found, swapping
2670 the order if we detect overlap. */
2671 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2672 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2674 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2675 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2679 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2680 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2684 [(set_attr "length" "2")])
2686 (define_insn_and_split "*movtf_cc_reg_sp64"
2687 [(set (match_operand:TF 0 "register_operand" "=e,e")
2688 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2689 [(match_operand:DI 2 "register_operand" "r,r")
2691 (match_operand:TF 3 "register_operand" "e,0")
2692 (match_operand:TF 4 "register_operand" "0,e")))]
2693 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
2695 "&& reload_completed"
2696 [(clobber (const_int 0))]
2698 rtx set_dest = operands[0];
2699 rtx set_srca = operands[3];
2700 rtx set_srcb = operands[4];
2701 int third = rtx_equal_p (set_dest, set_srca);
2703 rtx srca1, srca2, srcb1, srcb2;
2705 dest1 = gen_df_reg (set_dest, 0);
2706 dest2 = gen_df_reg (set_dest, 1);
2707 srca1 = gen_df_reg (set_srca, 0);
2708 srca2 = gen_df_reg (set_srca, 1);
2709 srcb1 = gen_df_reg (set_srcb, 0);
2710 srcb2 = gen_df_reg (set_srcb, 1);
2712 /* Now emit using the real source and destination we found, swapping
2713 the order if we detect overlap. */
2714 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2715 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2717 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2718 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2722 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2723 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2727 [(set_attr "length" "2")])
2730 ;; Zero-extension instructions
2732 ;; These patterns originally accepted general_operands, however, slightly
2733 ;; better code is generated by only accepting register_operands, and then
2734 ;; letting combine generate the ldu[hb] insns.
2736 (define_expand "zero_extendhisi2"
2737 [(set (match_operand:SI 0 "register_operand" "")
2738 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2741 rtx temp = gen_reg_rtx (SImode);
2742 rtx shift_16 = GEN_INT (16);
2743 int op1_subbyte = 0;
2745 if (GET_CODE (operand1) == SUBREG)
2747 op1_subbyte = SUBREG_BYTE (operand1);
2748 op1_subbyte /= GET_MODE_SIZE (SImode);
2749 op1_subbyte *= GET_MODE_SIZE (SImode);
2750 operand1 = XEXP (operand1, 0);
2753 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2755 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2759 (define_insn "*zero_extendhisi2_insn"
2760 [(set (match_operand:SI 0 "register_operand" "=r")
2761 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2764 [(set_attr "type" "load")
2765 (set_attr "us3load_type" "3cycle")])
2767 (define_expand "zero_extendqihi2"
2768 [(set (match_operand:HI 0 "register_operand" "")
2769 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2773 (define_insn "*zero_extendqihi2_insn"
2774 [(set (match_operand:HI 0 "register_operand" "=r,r")
2775 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
2776 "GET_CODE (operands[1]) != CONST_INT"
2780 [(set_attr "type" "*,load")
2781 (set_attr "us3load_type" "*,3cycle")])
2783 (define_expand "zero_extendqisi2"
2784 [(set (match_operand:SI 0 "register_operand" "")
2785 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2789 (define_insn "*zero_extendqisi2_insn"
2790 [(set (match_operand:SI 0 "register_operand" "=r,r")
2791 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
2792 "GET_CODE (operands[1]) != CONST_INT"
2796 [(set_attr "type" "*,load")
2797 (set_attr "us3load_type" "*,3cycle")])
2799 (define_expand "zero_extendqidi2"
2800 [(set (match_operand:DI 0 "register_operand" "")
2801 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2805 (define_insn "*zero_extendqidi2_insn"
2806 [(set (match_operand:DI 0 "register_operand" "=r,r")
2807 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
2808 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2812 [(set_attr "type" "*,load")
2813 (set_attr "us3load_type" "*,3cycle")])
2815 (define_expand "zero_extendhidi2"
2816 [(set (match_operand:DI 0 "register_operand" "")
2817 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2820 rtx temp = gen_reg_rtx (DImode);
2821 rtx shift_48 = GEN_INT (48);
2822 int op1_subbyte = 0;
2824 if (GET_CODE (operand1) == SUBREG)
2826 op1_subbyte = SUBREG_BYTE (operand1);
2827 op1_subbyte /= GET_MODE_SIZE (DImode);
2828 op1_subbyte *= GET_MODE_SIZE (DImode);
2829 operand1 = XEXP (operand1, 0);
2832 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
2834 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
2838 (define_insn "*zero_extendhidi2_insn"
2839 [(set (match_operand:DI 0 "register_operand" "=r")
2840 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2843 [(set_attr "type" "load")
2844 (set_attr "us3load_type" "3cycle")])
2846 ;; ??? Write truncdisi pattern using sra?
2848 (define_expand "zero_extendsidi2"
2849 [(set (match_operand:DI 0 "register_operand" "")
2850 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
2854 (define_insn "*zero_extendsidi2_insn_sp64"
2855 [(set (match_operand:DI 0 "register_operand" "=r,r")
2856 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
2857 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2861 [(set_attr "type" "shift,load")])
2863 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
2864 [(set (match_operand:DI 0 "register_operand" "=r")
2865 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
2868 "&& reload_completed"
2869 [(set (match_dup 2) (match_dup 3))
2870 (set (match_dup 4) (match_dup 5))]
2874 dest1 = gen_highpart (SImode, operands[0]);
2875 dest2 = gen_lowpart (SImode, operands[0]);
2877 /* Swap the order in case of overlap. */
2878 if (REGNO (dest1) == REGNO (operands[1]))
2880 operands[2] = dest2;
2881 operands[3] = operands[1];
2882 operands[4] = dest1;
2883 operands[5] = const0_rtx;
2887 operands[2] = dest1;
2888 operands[3] = const0_rtx;
2889 operands[4] = dest2;
2890 operands[5] = operands[1];
2893 [(set_attr "length" "2")])
2895 ;; Simplify comparisons of extended values.
2897 (define_insn "*cmp_zero_extendqisi2"
2899 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
2902 "andcc\t%0, 0xff, %%g0"
2903 [(set_attr "type" "compare")])
2905 (define_insn "*cmp_zero_qi"
2907 (compare:CC (match_operand:QI 0 "register_operand" "r")
2910 "andcc\t%0, 0xff, %%g0"
2911 [(set_attr "type" "compare")])
2913 (define_insn "*cmp_zero_extendqisi2_set"
2915 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
2917 (set (match_operand:SI 0 "register_operand" "=r")
2918 (zero_extend:SI (match_dup 1)))]
2920 "andcc\t%1, 0xff, %0"
2921 [(set_attr "type" "compare")])
2923 (define_insn "*cmp_zero_extendqisi2_andcc_set"
2925 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
2928 (set (match_operand:SI 0 "register_operand" "=r")
2929 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
2931 "andcc\t%1, 0xff, %0"
2932 [(set_attr "type" "compare")])
2934 (define_insn "*cmp_zero_extendqidi2"
2936 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
2939 "andcc\t%0, 0xff, %%g0"
2940 [(set_attr "type" "compare")])
2942 (define_insn "*cmp_zero_qi_sp64"
2944 (compare:CCX (match_operand:QI 0 "register_operand" "r")
2947 "andcc\t%0, 0xff, %%g0"
2948 [(set_attr "type" "compare")])
2950 (define_insn "*cmp_zero_extendqidi2_set"
2952 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
2954 (set (match_operand:DI 0 "register_operand" "=r")
2955 (zero_extend:DI (match_dup 1)))]
2957 "andcc\t%1, 0xff, %0"
2958 [(set_attr "type" "compare")])
2960 (define_insn "*cmp_zero_extendqidi2_andcc_set"
2962 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
2965 (set (match_operand:DI 0 "register_operand" "=r")
2966 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
2968 "andcc\t%1, 0xff, %0"
2969 [(set_attr "type" "compare")])
2971 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
2973 (define_insn "*cmp_siqi_trunc"
2975 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
2978 "andcc\t%0, 0xff, %%g0"
2979 [(set_attr "type" "compare")])
2981 (define_insn "*cmp_siqi_trunc_set"
2983 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
2985 (set (match_operand:QI 0 "register_operand" "=r")
2986 (subreg:QI (match_dup 1) 3))]
2988 "andcc\t%1, 0xff, %0"
2989 [(set_attr "type" "compare")])
2991 (define_insn "*cmp_diqi_trunc"
2993 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
2996 "andcc\t%0, 0xff, %%g0"
2997 [(set_attr "type" "compare")])
2999 (define_insn "*cmp_diqi_trunc_set"
3001 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3003 (set (match_operand:QI 0 "register_operand" "=r")
3004 (subreg:QI (match_dup 1) 7))]
3006 "andcc\t%1, 0xff, %0"
3007 [(set_attr "type" "compare")])
3010 ;; Sign-extension instructions
3012 ;; These patterns originally accepted general_operands, however, slightly
3013 ;; better code is generated by only accepting register_operands, and then
3014 ;; letting combine generate the lds[hb] insns.
3016 (define_expand "extendhisi2"
3017 [(set (match_operand:SI 0 "register_operand" "")
3018 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3021 rtx temp = gen_reg_rtx (SImode);
3022 rtx shift_16 = GEN_INT (16);
3023 int op1_subbyte = 0;
3025 if (GET_CODE (operand1) == SUBREG)
3027 op1_subbyte = SUBREG_BYTE (operand1);
3028 op1_subbyte /= GET_MODE_SIZE (SImode);
3029 op1_subbyte *= GET_MODE_SIZE (SImode);
3030 operand1 = XEXP (operand1, 0);
3033 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3035 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3039 (define_insn "*sign_extendhisi2_insn"
3040 [(set (match_operand:SI 0 "register_operand" "=r")
3041 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3044 [(set_attr "type" "sload")
3045 (set_attr "us3load_type" "3cycle")])
3047 (define_expand "extendqihi2"
3048 [(set (match_operand:HI 0 "register_operand" "")
3049 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3052 rtx temp = gen_reg_rtx (SImode);
3053 rtx shift_24 = GEN_INT (24);
3054 int op1_subbyte = 0;
3055 int op0_subbyte = 0;
3057 if (GET_CODE (operand1) == SUBREG)
3059 op1_subbyte = SUBREG_BYTE (operand1);
3060 op1_subbyte /= GET_MODE_SIZE (SImode);
3061 op1_subbyte *= GET_MODE_SIZE (SImode);
3062 operand1 = XEXP (operand1, 0);
3064 if (GET_CODE (operand0) == SUBREG)
3066 op0_subbyte = SUBREG_BYTE (operand0);
3067 op0_subbyte /= GET_MODE_SIZE (SImode);
3068 op0_subbyte *= GET_MODE_SIZE (SImode);
3069 operand0 = XEXP (operand0, 0);
3071 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3073 if (GET_MODE (operand0) != SImode)
3074 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3075 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3079 (define_insn "*sign_extendqihi2_insn"
3080 [(set (match_operand:HI 0 "register_operand" "=r")
3081 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3084 [(set_attr "type" "sload")
3085 (set_attr "us3load_type" "3cycle")])
3087 (define_expand "extendqisi2"
3088 [(set (match_operand:SI 0 "register_operand" "")
3089 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3092 rtx temp = gen_reg_rtx (SImode);
3093 rtx shift_24 = GEN_INT (24);
3094 int op1_subbyte = 0;
3096 if (GET_CODE (operand1) == SUBREG)
3098 op1_subbyte = SUBREG_BYTE (operand1);
3099 op1_subbyte /= GET_MODE_SIZE (SImode);
3100 op1_subbyte *= GET_MODE_SIZE (SImode);
3101 operand1 = XEXP (operand1, 0);
3104 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3106 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3110 (define_insn "*sign_extendqisi2_insn"
3111 [(set (match_operand:SI 0 "register_operand" "=r")
3112 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3115 [(set_attr "type" "sload")
3116 (set_attr "us3load_type" "3cycle")])
3118 (define_expand "extendqidi2"
3119 [(set (match_operand:DI 0 "register_operand" "")
3120 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3123 rtx temp = gen_reg_rtx (DImode);
3124 rtx shift_56 = GEN_INT (56);
3125 int op1_subbyte = 0;
3127 if (GET_CODE (operand1) == SUBREG)
3129 op1_subbyte = SUBREG_BYTE (operand1);
3130 op1_subbyte /= GET_MODE_SIZE (DImode);
3131 op1_subbyte *= GET_MODE_SIZE (DImode);
3132 operand1 = XEXP (operand1, 0);
3135 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3137 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3141 (define_insn "*sign_extendqidi2_insn"
3142 [(set (match_operand:DI 0 "register_operand" "=r")
3143 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3146 [(set_attr "type" "sload")
3147 (set_attr "us3load_type" "3cycle")])
3149 (define_expand "extendhidi2"
3150 [(set (match_operand:DI 0 "register_operand" "")
3151 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3154 rtx temp = gen_reg_rtx (DImode);
3155 rtx shift_48 = GEN_INT (48);
3156 int op1_subbyte = 0;
3158 if (GET_CODE (operand1) == SUBREG)
3160 op1_subbyte = SUBREG_BYTE (operand1);
3161 op1_subbyte /= GET_MODE_SIZE (DImode);
3162 op1_subbyte *= GET_MODE_SIZE (DImode);
3163 operand1 = XEXP (operand1, 0);
3166 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3168 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3172 (define_insn "*sign_extendhidi2_insn"
3173 [(set (match_operand:DI 0 "register_operand" "=r")
3174 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3177 [(set_attr "type" "sload")
3178 (set_attr "us3load_type" "3cycle")])
3180 (define_expand "extendsidi2"
3181 [(set (match_operand:DI 0 "register_operand" "")
3182 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3186 (define_insn "*sign_extendsidi2_insn"
3187 [(set (match_operand:DI 0 "register_operand" "=r,r")
3188 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3193 [(set_attr "type" "shift,sload")
3194 (set_attr "us3load_type" "*,3cycle")])
3197 ;; Special pattern for optimizing bit-field compares. This is needed
3198 ;; because combine uses this as a canonical form.
3200 (define_insn "*cmp_zero_extract"
3203 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3204 (match_operand:SI 1 "small_int_operand" "I")
3205 (match_operand:SI 2 "small_int_operand" "I"))
3207 "INTVAL (operands[2]) > 19"
3209 int len = INTVAL (operands[1]);
3210 int pos = 32 - INTVAL (operands[2]) - len;
3211 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3212 operands[1] = GEN_INT (mask);
3213 return "andcc\t%0, %1, %%g0";
3215 [(set_attr "type" "compare")])
3217 (define_insn "*cmp_zero_extract_sp64"
3220 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3221 (match_operand:SI 1 "small_int_operand" "I")
3222 (match_operand:SI 2 "small_int_operand" "I"))
3224 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3226 int len = INTVAL (operands[1]);
3227 int pos = 64 - INTVAL (operands[2]) - len;
3228 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3229 operands[1] = GEN_INT (mask);
3230 return "andcc\t%0, %1, %%g0";
3232 [(set_attr "type" "compare")])
3235 ;; Conversions between float, double and long double.
3237 (define_insn "extendsfdf2"
3238 [(set (match_operand:DF 0 "register_operand" "=e")
3240 (match_operand:SF 1 "register_operand" "f")))]
3243 [(set_attr "type" "fp")
3244 (set_attr "fptype" "double")])
3246 (define_expand "extendsftf2"
3247 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3249 (match_operand:SF 1 "register_operand" "")))]
3250 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3251 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3253 (define_insn "*extendsftf2_hq"
3254 [(set (match_operand:TF 0 "register_operand" "=e")
3256 (match_operand:SF 1 "register_operand" "f")))]
3257 "TARGET_FPU && TARGET_HARD_QUAD"
3259 [(set_attr "type" "fp")])
3261 (define_expand "extenddftf2"
3262 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3264 (match_operand:DF 1 "register_operand" "")))]
3265 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3266 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3268 (define_insn "*extenddftf2_hq"
3269 [(set (match_operand:TF 0 "register_operand" "=e")
3271 (match_operand:DF 1 "register_operand" "e")))]
3272 "TARGET_FPU && TARGET_HARD_QUAD"
3274 [(set_attr "type" "fp")])
3276 (define_insn "truncdfsf2"
3277 [(set (match_operand:SF 0 "register_operand" "=f")
3279 (match_operand:DF 1 "register_operand" "e")))]
3282 [(set_attr "type" "fp")
3283 (set_attr "fptype" "double")])
3285 (define_expand "trunctfsf2"
3286 [(set (match_operand:SF 0 "register_operand" "")
3288 (match_operand:TF 1 "general_operand" "")))]
3289 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3290 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3292 (define_insn "*trunctfsf2_hq"
3293 [(set (match_operand:SF 0 "register_operand" "=f")
3295 (match_operand:TF 1 "register_operand" "e")))]
3296 "TARGET_FPU && TARGET_HARD_QUAD"
3298 [(set_attr "type" "fp")])
3300 (define_expand "trunctfdf2"
3301 [(set (match_operand:DF 0 "register_operand" "")
3303 (match_operand:TF 1 "general_operand" "")))]
3304 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3305 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3307 (define_insn "*trunctfdf2_hq"
3308 [(set (match_operand:DF 0 "register_operand" "=e")
3310 (match_operand:TF 1 "register_operand" "e")))]
3311 "TARGET_FPU && TARGET_HARD_QUAD"
3313 [(set_attr "type" "fp")])
3316 ;; Conversion between fixed point and floating point.
3318 (define_insn "floatsisf2"
3319 [(set (match_operand:SF 0 "register_operand" "=f")
3320 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3323 [(set_attr "type" "fp")
3324 (set_attr "fptype" "double")])
3326 (define_insn "floatsidf2"
3327 [(set (match_operand:DF 0 "register_operand" "=e")
3328 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3331 [(set_attr "type" "fp")
3332 (set_attr "fptype" "double")])
3334 (define_expand "floatsitf2"
3335 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3336 (float:TF (match_operand:SI 1 "register_operand" "")))]
3337 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3338 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3340 (define_insn "*floatsitf2_hq"
3341 [(set (match_operand:TF 0 "register_operand" "=e")
3342 (float:TF (match_operand:SI 1 "register_operand" "f")))]
3343 "TARGET_FPU && TARGET_HARD_QUAD"
3345 [(set_attr "type" "fp")])
3347 (define_expand "floatunssitf2"
3348 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3349 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3350 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3351 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3353 ;; Now the same for 64 bit sources.
3355 (define_insn "floatdisf2"
3356 [(set (match_operand:SF 0 "register_operand" "=f")
3357 (float:SF (match_operand:DI 1 "register_operand" "e")))]
3358 "TARGET_V9 && TARGET_FPU"
3360 [(set_attr "type" "fp")
3361 (set_attr "fptype" "double")])
3363 (define_expand "floatunsdisf2"
3364 [(use (match_operand:SF 0 "register_operand" ""))
3365 (use (match_operand:DI 1 "general_operand" ""))]
3366 "TARGET_ARCH64 && TARGET_FPU"
3367 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3369 (define_insn "floatdidf2"
3370 [(set (match_operand:DF 0 "register_operand" "=e")
3371 (float:DF (match_operand:DI 1 "register_operand" "e")))]
3372 "TARGET_V9 && TARGET_FPU"
3374 [(set_attr "type" "fp")
3375 (set_attr "fptype" "double")])
3377 (define_expand "floatunsdidf2"
3378 [(use (match_operand:DF 0 "register_operand" ""))
3379 (use (match_operand:DI 1 "general_operand" ""))]
3380 "TARGET_ARCH64 && TARGET_FPU"
3381 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3383 (define_expand "floatditf2"
3384 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3385 (float:TF (match_operand:DI 1 "register_operand" "")))]
3386 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3387 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3389 (define_insn "*floatditf2_hq"
3390 [(set (match_operand:TF 0 "register_operand" "=e")
3391 (float:TF (match_operand:DI 1 "register_operand" "e")))]
3392 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3394 [(set_attr "type" "fp")])
3396 (define_expand "floatunsditf2"
3397 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3398 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3399 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3400 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3402 ;; Convert a float to an actual integer.
3403 ;; Truncation is performed as part of the conversion.
3405 (define_insn "fix_truncsfsi2"
3406 [(set (match_operand:SI 0 "register_operand" "=f")
3407 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3410 [(set_attr "type" "fp")
3411 (set_attr "fptype" "double")])
3413 (define_insn "fix_truncdfsi2"
3414 [(set (match_operand:SI 0 "register_operand" "=f")
3415 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3418 [(set_attr "type" "fp")
3419 (set_attr "fptype" "double")])
3421 (define_expand "fix_trunctfsi2"
3422 [(set (match_operand:SI 0 "register_operand" "")
3423 (fix:SI (match_operand:TF 1 "general_operand" "")))]
3424 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3425 "emit_tfmode_cvt (FIX, operands); DONE;")
3427 (define_insn "*fix_trunctfsi2_hq"
3428 [(set (match_operand:SI 0 "register_operand" "=f")
3429 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
3430 "TARGET_FPU && TARGET_HARD_QUAD"
3432 [(set_attr "type" "fp")])
3434 (define_expand "fixuns_trunctfsi2"
3435 [(set (match_operand:SI 0 "register_operand" "")
3436 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
3437 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3438 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3440 ;; Now the same, for V9 targets
3442 (define_insn "fix_truncsfdi2"
3443 [(set (match_operand:DI 0 "register_operand" "=e")
3444 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3445 "TARGET_V9 && TARGET_FPU"
3447 [(set_attr "type" "fp")
3448 (set_attr "fptype" "double")])
3450 (define_expand "fixuns_truncsfdi2"
3451 [(use (match_operand:DI 0 "register_operand" ""))
3452 (use (match_operand:SF 1 "general_operand" ""))]
3453 "TARGET_ARCH64 && TARGET_FPU"
3454 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
3456 (define_insn "fix_truncdfdi2"
3457 [(set (match_operand:DI 0 "register_operand" "=e")
3458 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3459 "TARGET_V9 && TARGET_FPU"
3461 [(set_attr "type" "fp")
3462 (set_attr "fptype" "double")])
3464 (define_expand "fixuns_truncdfdi2"
3465 [(use (match_operand:DI 0 "register_operand" ""))
3466 (use (match_operand:DF 1 "general_operand" ""))]
3467 "TARGET_ARCH64 && TARGET_FPU"
3468 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
3470 (define_expand "fix_trunctfdi2"
3471 [(set (match_operand:DI 0 "register_operand" "")
3472 (fix:DI (match_operand:TF 1 "general_operand" "")))]
3473 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3474 "emit_tfmode_cvt (FIX, operands); DONE;")
3476 (define_insn "*fix_trunctfdi2_hq"
3477 [(set (match_operand:DI 0 "register_operand" "=e")
3478 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
3479 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3481 [(set_attr "type" "fp")])
3483 (define_expand "fixuns_trunctfdi2"
3484 [(set (match_operand:DI 0 "register_operand" "")
3485 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
3486 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3487 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3490 ;; Integer addition/subtraction instructions.
3492 (define_expand "adddi3"
3493 [(set (match_operand:DI 0 "register_operand" "")
3494 (plus:DI (match_operand:DI 1 "register_operand" "")
3495 (match_operand:DI 2 "arith_double_add_operand" "")))]
3498 if (! TARGET_ARCH64)
3500 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3501 gen_rtx_SET (VOIDmode, operands[0],
3502 gen_rtx_PLUS (DImode, operands[1],
3504 gen_rtx_CLOBBER (VOIDmode,
3505 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3510 (define_insn_and_split "adddi3_insn_sp32"
3511 [(set (match_operand:DI 0 "register_operand" "=r")
3512 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3513 (match_operand:DI 2 "arith_double_operand" "rHI")))
3514 (clobber (reg:CC 100))]
3517 "&& reload_completed"
3518 [(parallel [(set (reg:CC_NOOV 100)
3519 (compare:CC_NOOV (plus:SI (match_dup 4)
3523 (plus:SI (match_dup 4) (match_dup 5)))])
3525 (plus:SI (plus:SI (match_dup 7)
3527 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3529 operands[3] = gen_lowpart (SImode, operands[0]);
3530 operands[4] = gen_lowpart (SImode, operands[1]);
3531 operands[5] = gen_lowpart (SImode, operands[2]);
3532 operands[6] = gen_highpart (SImode, operands[0]);
3533 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3534 #if HOST_BITS_PER_WIDE_INT == 32
3535 if (GET_CODE (operands[2]) == CONST_INT)
3537 if (INTVAL (operands[2]) < 0)
3538 operands[8] = constm1_rtx;
3540 operands[8] = const0_rtx;
3544 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3546 [(set_attr "length" "2")])
3548 ;; LTU here means "carry set"
3550 [(set (match_operand:SI 0 "register_operand" "=r")
3551 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3552 (match_operand:SI 2 "arith_operand" "rI"))
3553 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3556 [(set_attr "type" "ialuX")])
3558 (define_insn_and_split "*addx_extend_sp32"
3559 [(set (match_operand:DI 0 "register_operand" "=r")
3560 (zero_extend:DI (plus:SI (plus:SI
3561 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3562 (match_operand:SI 2 "arith_operand" "rI"))
3563 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3566 "&& reload_completed"
3567 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
3568 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
3569 (set (match_dup 4) (const_int 0))]
3570 "operands[3] = gen_lowpart (SImode, operands[0]);
3571 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
3572 [(set_attr "length" "2")])
3574 (define_insn "*addx_extend_sp64"
3575 [(set (match_operand:DI 0 "register_operand" "=r")
3576 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3577 (match_operand:SI 2 "arith_operand" "rI"))
3578 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3581 [(set_attr "type" "ialuX")])
3583 (define_insn_and_split ""
3584 [(set (match_operand:DI 0 "register_operand" "=r")
3585 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3586 (match_operand:DI 2 "register_operand" "r")))
3587 (clobber (reg:CC 100))]
3590 "&& reload_completed"
3591 [(parallel [(set (reg:CC_NOOV 100)
3592 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
3594 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
3596 (plus:SI (plus:SI (match_dup 4) (const_int 0))
3597 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3598 "operands[3] = gen_lowpart (SImode, operands[2]);
3599 operands[4] = gen_highpart (SImode, operands[2]);
3600 operands[5] = gen_lowpart (SImode, operands[0]);
3601 operands[6] = gen_highpart (SImode, operands[0]);"
3602 [(set_attr "length" "2")])
3604 (define_insn "*adddi3_sp64"
3605 [(set (match_operand:DI 0 "register_operand" "=r,r")
3606 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3607 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3613 (define_insn "addsi3"
3614 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3615 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
3616 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3621 fpadd32s\t%1, %2, %0"
3622 [(set_attr "type" "*,*,fga")
3623 (set_attr "fptype" "*,*,single")])
3625 (define_insn "*cmp_cc_plus"
3626 [(set (reg:CC_NOOV 100)
3627 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3628 (match_operand:SI 1 "arith_operand" "rI"))
3631 "addcc\t%0, %1, %%g0"
3632 [(set_attr "type" "compare")])
3634 (define_insn "*cmp_ccx_plus"
3635 [(set (reg:CCX_NOOV 100)
3636 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
3637 (match_operand:DI 1 "arith_operand" "rI"))
3640 "addcc\t%0, %1, %%g0"
3641 [(set_attr "type" "compare")])
3643 (define_insn "*cmp_cc_plus_set"
3644 [(set (reg:CC_NOOV 100)
3645 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3646 (match_operand:SI 2 "arith_operand" "rI"))
3648 (set (match_operand:SI 0 "register_operand" "=r")
3649 (plus:SI (match_dup 1) (match_dup 2)))]
3652 [(set_attr "type" "compare")])
3654 (define_insn "*cmp_ccx_plus_set"
3655 [(set (reg:CCX_NOOV 100)
3656 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
3657 (match_operand:DI 2 "arith_operand" "rI"))
3659 (set (match_operand:DI 0 "register_operand" "=r")
3660 (plus:DI (match_dup 1) (match_dup 2)))]
3663 [(set_attr "type" "compare")])
3665 (define_expand "subdi3"
3666 [(set (match_operand:DI 0 "register_operand" "")
3667 (minus:DI (match_operand:DI 1 "register_operand" "")
3668 (match_operand:DI 2 "arith_double_add_operand" "")))]
3671 if (! TARGET_ARCH64)
3673 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3674 gen_rtx_SET (VOIDmode, operands[0],
3675 gen_rtx_MINUS (DImode, operands[1],
3677 gen_rtx_CLOBBER (VOIDmode,
3678 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3683 (define_insn_and_split "subdi3_insn_sp32"
3684 [(set (match_operand:DI 0 "register_operand" "=r")
3685 (minus:DI (match_operand:DI 1 "register_operand" "r")
3686 (match_operand:DI 2 "arith_double_operand" "rHI")))
3687 (clobber (reg:CC 100))]
3690 "&& reload_completed"
3691 [(parallel [(set (reg:CC_NOOV 100)
3692 (compare:CC_NOOV (minus:SI (match_dup 4)
3696 (minus:SI (match_dup 4) (match_dup 5)))])
3698 (minus:SI (minus:SI (match_dup 7)
3700 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3702 operands[3] = gen_lowpart (SImode, operands[0]);
3703 operands[4] = gen_lowpart (SImode, operands[1]);
3704 operands[5] = gen_lowpart (SImode, operands[2]);
3705 operands[6] = gen_highpart (SImode, operands[0]);
3706 operands[7] = gen_highpart (SImode, operands[1]);
3707 #if HOST_BITS_PER_WIDE_INT == 32
3708 if (GET_CODE (operands[2]) == CONST_INT)
3710 if (INTVAL (operands[2]) < 0)
3711 operands[8] = constm1_rtx;
3713 operands[8] = const0_rtx;
3717 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3719 [(set_attr "length" "2")])
3721 ;; LTU here means "carry set"
3723 [(set (match_operand:SI 0 "register_operand" "=r")
3724 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3725 (match_operand:SI 2 "arith_operand" "rI"))
3726 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3729 [(set_attr "type" "ialuX")])
3731 (define_insn "*subx_extend_sp64"
3732 [(set (match_operand:DI 0 "register_operand" "=r")
3733 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3734 (match_operand:SI 2 "arith_operand" "rI"))
3735 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3738 [(set_attr "type" "ialuX")])
3740 (define_insn_and_split "*subx_extend"
3741 [(set (match_operand:DI 0 "register_operand" "=r")
3742 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3743 (match_operand:SI 2 "arith_operand" "rI"))
3744 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3747 "&& reload_completed"
3748 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
3749 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
3750 (set (match_dup 4) (const_int 0))]
3751 "operands[3] = gen_lowpart (SImode, operands[0]);
3752 operands[4] = gen_highpart (SImode, operands[0]);"
3753 [(set_attr "length" "2")])
3755 (define_insn_and_split ""
3756 [(set (match_operand:DI 0 "register_operand" "=r")
3757 (minus:DI (match_operand:DI 1 "register_operand" "r")
3758 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
3759 (clobber (reg:CC 100))]
3762 "&& reload_completed"
3763 [(parallel [(set (reg:CC_NOOV 100)
3764 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
3766 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
3768 (minus:SI (minus:SI (match_dup 4) (const_int 0))
3769 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3770 "operands[3] = gen_lowpart (SImode, operands[1]);
3771 operands[4] = gen_highpart (SImode, operands[1]);
3772 operands[5] = gen_lowpart (SImode, operands[0]);
3773 operands[6] = gen_highpart (SImode, operands[0]);"
3774 [(set_attr "length" "2")])
3776 (define_insn "*subdi3_sp64"
3777 [(set (match_operand:DI 0 "register_operand" "=r,r")
3778 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
3779 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3785 (define_insn "subsi3"
3786 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3787 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
3788 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3793 fpsub32s\t%1, %2, %0"
3794 [(set_attr "type" "*,*,fga")
3795 (set_attr "fptype" "*,*,single")])
3797 (define_insn "*cmp_minus_cc"
3798 [(set (reg:CC_NOOV 100)
3799 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
3800 (match_operand:SI 1 "arith_operand" "rI"))
3803 "subcc\t%r0, %1, %%g0"
3804 [(set_attr "type" "compare")])
3806 (define_insn "*cmp_minus_ccx"
3807 [(set (reg:CCX_NOOV 100)
3808 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
3809 (match_operand:DI 1 "arith_operand" "rI"))
3812 "subcc\t%0, %1, %%g0"
3813 [(set_attr "type" "compare")])
3815 (define_insn "cmp_minus_cc_set"
3816 [(set (reg:CC_NOOV 100)
3817 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3818 (match_operand:SI 2 "arith_operand" "rI"))
3820 (set (match_operand:SI 0 "register_operand" "=r")
3821 (minus:SI (match_dup 1) (match_dup 2)))]
3823 "subcc\t%r1, %2, %0"
3824 [(set_attr "type" "compare")])
3826 (define_insn "*cmp_minus_ccx_set"
3827 [(set (reg:CCX_NOOV 100)
3828 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
3829 (match_operand:DI 2 "arith_operand" "rI"))
3831 (set (match_operand:DI 0 "register_operand" "=r")
3832 (minus:DI (match_dup 1) (match_dup 2)))]
3835 [(set_attr "type" "compare")])
3838 ;; Integer multiply/divide instructions.
3840 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
3841 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
3843 (define_insn "mulsi3"
3844 [(set (match_operand:SI 0 "register_operand" "=r")
3845 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3846 (match_operand:SI 2 "arith_operand" "rI")))]
3849 [(set_attr "type" "imul")])
3851 (define_expand "muldi3"
3852 [(set (match_operand:DI 0 "register_operand" "")
3853 (mult:DI (match_operand:DI 1 "arith_operand" "")
3854 (match_operand:DI 2 "arith_operand" "")))]
3855 "TARGET_ARCH64 || TARGET_V8PLUS"
3859 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
3864 (define_insn "*muldi3_sp64"
3865 [(set (match_operand:DI 0 "register_operand" "=r")
3866 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
3867 (match_operand:DI 2 "arith_operand" "rI")))]
3870 [(set_attr "type" "imul")])
3872 ;; V8plus wide multiply.
3874 (define_insn "muldi3_v8plus"
3875 [(set (match_operand:DI 0 "register_operand" "=r,h")
3876 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
3877 (match_operand:DI 2 "arith_operand" "rI,rI")))
3878 (clobber (match_scratch:SI 3 "=&h,X"))
3879 (clobber (match_scratch:SI 4 "=&h,X"))]
3882 if (sparc_check_64 (operands[1], insn) <= 0)
3883 output_asm_insn ("srl\t%L1, 0, %L1", operands);
3884 if (which_alternative == 1)
3885 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
3886 if (GET_CODE (operands[2]) == CONST_INT)
3888 if (which_alternative == 1)
3889 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
3891 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";
3893 else if (rtx_equal_p (operands[1], operands[2]))
3895 if (which_alternative == 1)
3896 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
3898 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";
3900 if (sparc_check_64 (operands[2], insn) <= 0)
3901 output_asm_insn ("srl\t%L2, 0, %L2", operands);
3902 if (which_alternative == 1)
3903 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";
3905 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";
3907 [(set_attr "type" "multi")
3908 (set_attr "length" "9,8")])
3910 (define_insn "*cmp_mul_set"
3912 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3913 (match_operand:SI 2 "arith_operand" "rI"))
3915 (set (match_operand:SI 0 "register_operand" "=r")
3916 (mult:SI (match_dup 1) (match_dup 2)))]
3917 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
3918 "smulcc\t%1, %2, %0"
3919 [(set_attr "type" "imul")])
3921 (define_expand "mulsidi3"
3922 [(set (match_operand:DI 0 "register_operand" "")
3923 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
3924 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
3927 if (CONSTANT_P (operands[2]))
3930 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
3932 else if (TARGET_ARCH32)
3933 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
3936 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
3942 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
3947 ;; V9 puts the 64-bit product in a 64-bit register. Only out or global
3948 ;; registers can hold 64-bit values in the V8plus environment.
3950 (define_insn "mulsidi3_v8plus"
3951 [(set (match_operand:DI 0 "register_operand" "=h,r")
3952 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
3953 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
3954 (clobber (match_scratch:SI 3 "=X,&h"))]
3957 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
3958 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
3959 [(set_attr "type" "multi")
3960 (set_attr "length" "2,3")])
3963 (define_insn "const_mulsidi3_v8plus"
3964 [(set (match_operand:DI 0 "register_operand" "=h,r")
3965 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
3966 (match_operand:DI 2 "small_int_operand" "I,I")))
3967 (clobber (match_scratch:SI 3 "=X,&h"))]
3970 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
3971 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
3972 [(set_attr "type" "multi")
3973 (set_attr "length" "2,3")])
3976 (define_insn "*mulsidi3_sp32"
3977 [(set (match_operand:DI 0 "register_operand" "=r")
3978 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3979 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
3982 return TARGET_SPARCLET
3983 ? "smuld\t%1, %2, %L0"
3984 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
3987 (if_then_else (eq_attr "isa" "sparclet")
3988 (const_string "imul") (const_string "multi")))
3989 (set (attr "length")
3990 (if_then_else (eq_attr "isa" "sparclet")
3991 (const_int 1) (const_int 2)))])
3993 (define_insn "*mulsidi3_sp64"
3994 [(set (match_operand:DI 0 "register_operand" "=r")
3995 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3996 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
3997 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
3999 [(set_attr "type" "imul")])
4001 ;; Extra pattern, because sign_extend of a constant isn't valid.
4004 (define_insn "const_mulsidi3_sp32"
4005 [(set (match_operand:DI 0 "register_operand" "=r")
4006 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4007 (match_operand:DI 2 "small_int_operand" "I")))]
4010 return TARGET_SPARCLET
4011 ? "smuld\t%1, %2, %L0"
4012 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4015 (if_then_else (eq_attr "isa" "sparclet")
4016 (const_string "imul") (const_string "multi")))
4017 (set (attr "length")
4018 (if_then_else (eq_attr "isa" "sparclet")
4019 (const_int 1) (const_int 2)))])
4021 (define_insn "const_mulsidi3_sp64"
4022 [(set (match_operand:DI 0 "register_operand" "=r")
4023 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4024 (match_operand:DI 2 "small_int_operand" "I")))]
4025 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4027 [(set_attr "type" "imul")])
4029 (define_expand "smulsi3_highpart"
4030 [(set (match_operand:SI 0 "register_operand" "")
4032 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4033 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4035 "TARGET_HARD_MUL && TARGET_ARCH32"
4037 if (CONSTANT_P (operands[2]))
4041 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4047 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4052 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4053 operands[2], GEN_INT (32)));
4059 (define_insn "smulsi3_highpart_v8plus"
4060 [(set (match_operand:SI 0 "register_operand" "=h,r")
4062 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4063 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4064 (match_operand:SI 3 "small_int_operand" "I,I"))))
4065 (clobber (match_scratch:SI 4 "=X,&h"))]
4068 smul\t%1, %2, %0\;srlx\t%0, %3, %0
4069 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4070 [(set_attr "type" "multi")
4071 (set_attr "length" "2")])
4073 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4076 [(set (match_operand:SI 0 "register_operand" "=h,r")
4079 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4080 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4081 (match_operand:SI 3 "small_int_operand" "I,I"))
4083 (clobber (match_scratch:SI 4 "=X,&h"))]
4086 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4087 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4088 [(set_attr "type" "multi")
4089 (set_attr "length" "2")])
4092 (define_insn "const_smulsi3_highpart_v8plus"
4093 [(set (match_operand:SI 0 "register_operand" "=h,r")
4095 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4096 (match_operand:DI 2 "small_int_operand" "I,I"))
4097 (match_operand:SI 3 "small_int_operand" "I,I"))))
4098 (clobber (match_scratch:SI 4 "=X,&h"))]
4101 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4102 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4103 [(set_attr "type" "multi")
4104 (set_attr "length" "2")])
4107 (define_insn "*smulsi3_highpart_sp32"
4108 [(set (match_operand:SI 0 "register_operand" "=r")
4110 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4111 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4114 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4115 [(set_attr "type" "multi")
4116 (set_attr "length" "2")])
4119 (define_insn "const_smulsi3_highpart"
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 (match_operand:DI 2 "small_int_operand" "i"))
4126 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4127 [(set_attr "type" "multi")
4128 (set_attr "length" "2")])
4130 (define_expand "umulsidi3"
4131 [(set (match_operand:DI 0 "register_operand" "")
4132 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4133 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4136 if (CONSTANT_P (operands[2]))
4139 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4141 else if (TARGET_ARCH32)
4142 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4145 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4151 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4157 (define_insn "umulsidi3_v8plus"
4158 [(set (match_operand:DI 0 "register_operand" "=h,r")
4159 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4160 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4161 (clobber (match_scratch:SI 3 "=X,&h"))]
4164 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4165 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4166 [(set_attr "type" "multi")
4167 (set_attr "length" "2,3")])
4170 (define_insn "*umulsidi3_sp32"
4171 [(set (match_operand:DI 0 "register_operand" "=r")
4172 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4173 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4176 return TARGET_SPARCLET
4177 ? "umuld\t%1, %2, %L0"
4178 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4181 (if_then_else (eq_attr "isa" "sparclet")
4182 (const_string "imul") (const_string "multi")))
4183 (set (attr "length")
4184 (if_then_else (eq_attr "isa" "sparclet")
4185 (const_int 1) (const_int 2)))])
4187 (define_insn "*umulsidi3_sp64"
4188 [(set (match_operand:DI 0 "register_operand" "=r")
4189 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4190 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4191 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4193 [(set_attr "type" "imul")])
4195 ;; Extra pattern, because sign_extend of a constant isn't valid.
4198 (define_insn "const_umulsidi3_sp32"
4199 [(set (match_operand:DI 0 "register_operand" "=r")
4200 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4201 (match_operand:DI 2 "uns_small_int_operand" "")))]
4204 return TARGET_SPARCLET
4205 ? "umuld\t%1, %s2, %L0"
4206 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4209 (if_then_else (eq_attr "isa" "sparclet")
4210 (const_string "imul") (const_string "multi")))
4211 (set (attr "length")
4212 (if_then_else (eq_attr "isa" "sparclet")
4213 (const_int 1) (const_int 2)))])
4215 (define_insn "const_umulsidi3_sp64"
4216 [(set (match_operand:DI 0 "register_operand" "=r")
4217 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4218 (match_operand:DI 2 "uns_small_int_operand" "")))]
4219 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4221 [(set_attr "type" "imul")])
4224 (define_insn "const_umulsidi3_v8plus"
4225 [(set (match_operand:DI 0 "register_operand" "=h,r")
4226 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4227 (match_operand:DI 2 "uns_small_int_operand" "")))
4228 (clobber (match_scratch:SI 3 "=X,h"))]
4231 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4232 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4233 [(set_attr "type" "multi")
4234 (set_attr "length" "2,3")])
4236 (define_expand "umulsi3_highpart"
4237 [(set (match_operand:SI 0 "register_operand" "")
4239 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4240 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4242 "TARGET_HARD_MUL && TARGET_ARCH32"
4244 if (CONSTANT_P (operands[2]))
4248 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4254 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4259 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4260 operands[2], GEN_INT (32)));
4266 (define_insn "umulsi3_highpart_v8plus"
4267 [(set (match_operand:SI 0 "register_operand" "=h,r")
4269 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4270 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4271 (match_operand:SI 3 "small_int_operand" "I,I"))))
4272 (clobber (match_scratch:SI 4 "=X,h"))]
4275 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4276 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4277 [(set_attr "type" "multi")
4278 (set_attr "length" "2")])
4281 (define_insn "const_umulsi3_highpart_v8plus"
4282 [(set (match_operand:SI 0 "register_operand" "=h,r")
4284 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4285 (match_operand:DI 2 "uns_small_int_operand" ""))
4286 (match_operand:SI 3 "small_int_operand" "I,I"))))
4287 (clobber (match_scratch:SI 4 "=X,h"))]
4290 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4291 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4292 [(set_attr "type" "multi")
4293 (set_attr "length" "2")])
4296 (define_insn "*umulsi3_highpart_sp32"
4297 [(set (match_operand:SI 0 "register_operand" "=r")
4299 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4300 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4303 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4304 [(set_attr "type" "multi")
4305 (set_attr "length" "2")])
4308 (define_insn "const_umulsi3_highpart"
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 (match_operand:DI 2 "uns_small_int_operand" ""))
4315 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4316 [(set_attr "type" "multi")
4317 (set_attr "length" "2")])
4319 (define_expand "divsi3"
4320 [(parallel [(set (match_operand:SI 0 "register_operand" "")
4321 (div:SI (match_operand:SI 1 "register_operand" "")
4322 (match_operand:SI 2 "input_operand" "")))
4323 (clobber (match_scratch:SI 3 ""))])]
4324 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4328 operands[3] = gen_reg_rtx(SImode);
4329 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4330 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4336 ;; The V8 architecture specifies that there must be at least 3 instructions
4337 ;; between a write to the Y register and a use of it for correct results.
4338 ;; We try to fill one of them with a simple constant or a memory load.
4340 (define_insn "divsi3_sp32"
4341 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4342 (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4343 (match_operand:SI 2 "input_operand" "rI,K,m")))
4344 (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4345 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4347 output_asm_insn ("sra\t%1, 31, %3", operands);
4348 output_asm_insn ("wr\t%3, 0, %%y", operands);
4350 switch (which_alternative)
4354 return "sdiv\t%1, %2, %0";
4356 return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4359 return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4361 return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4364 return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4366 return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4371 [(set_attr "type" "multi")
4372 (set (attr "length")
4373 (if_then_else (eq_attr "isa" "v9")
4374 (const_int 4) (const_int 6)))])
4376 (define_insn "divsi3_sp64"
4377 [(set (match_operand:SI 0 "register_operand" "=r")
4378 (div:SI (match_operand:SI 1 "register_operand" "r")
4379 (match_operand:SI 2 "input_operand" "rI")))
4380 (use (match_operand:SI 3 "register_operand" "r"))]
4381 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4382 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4383 [(set_attr "type" "multi")
4384 (set_attr "length" "2")])
4386 (define_insn "divdi3"
4387 [(set (match_operand:DI 0 "register_operand" "=r")
4388 (div:DI (match_operand:DI 1 "register_operand" "r")
4389 (match_operand:DI 2 "arith_operand" "rI")))]
4392 [(set_attr "type" "idiv")])
4394 (define_insn "*cmp_sdiv_cc_set"
4396 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4397 (match_operand:SI 2 "arith_operand" "rI"))
4399 (set (match_operand:SI 0 "register_operand" "=r")
4400 (div:SI (match_dup 1) (match_dup 2)))
4401 (clobber (match_scratch:SI 3 "=&r"))]
4402 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4404 output_asm_insn ("sra\t%1, 31, %3", operands);
4405 output_asm_insn ("wr\t%3, 0, %%y", operands);
4408 return "sdivcc\t%1, %2, %0";
4410 return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4412 [(set_attr "type" "multi")
4413 (set (attr "length")
4414 (if_then_else (eq_attr "isa" "v9")
4415 (const_int 3) (const_int 6)))])
4418 (define_expand "udivsi3"
4419 [(set (match_operand:SI 0 "register_operand" "")
4420 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4421 (match_operand:SI 2 "input_operand" "")))]
4422 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4425 ;; The V8 architecture specifies that there must be at least 3 instructions
4426 ;; between a write to the Y register and a use of it for correct results.
4427 ;; We try to fill one of them with a simple constant or a memory load.
4429 (define_insn "udivsi3_sp32"
4430 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
4431 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
4432 (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
4433 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4435 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4437 switch (which_alternative)
4441 return "udiv\t%1, %2, %0";
4443 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
4446 return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
4448 return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4451 return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
4453 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4456 return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
4458 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
4463 [(set_attr "type" "multi")
4464 (set (attr "length")
4465 (if_then_else (eq_attr "isa" "v9")
4466 (const_int 3) (const_int 5)))])
4468 (define_insn "udivsi3_sp64"
4469 [(set (match_operand:SI 0 "register_operand" "=r")
4470 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
4471 (match_operand:SI 2 "input_operand" "rI")))]
4472 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4473 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
4474 [(set_attr "type" "multi")
4475 (set_attr "length" "2")])
4477 (define_insn "udivdi3"
4478 [(set (match_operand:DI 0 "register_operand" "=r")
4479 (udiv:DI (match_operand:DI 1 "register_operand" "r")
4480 (match_operand:DI 2 "arith_operand" "rI")))]
4483 [(set_attr "type" "idiv")])
4485 (define_insn "*cmp_udiv_cc_set"
4487 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
4488 (match_operand:SI 2 "arith_operand" "rI"))
4490 (set (match_operand:SI 0 "register_operand" "=r")
4491 (udiv:SI (match_dup 1) (match_dup 2)))]
4492 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4494 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4497 return "udivcc\t%1, %2, %0";
4499 return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
4501 [(set_attr "type" "multi")
4502 (set (attr "length")
4503 (if_then_else (eq_attr "isa" "v9")
4504 (const_int 2) (const_int 5)))])
4506 ; sparclet multiply/accumulate insns
4508 (define_insn "*smacsi"
4509 [(set (match_operand:SI 0 "register_operand" "=r")
4510 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
4511 (match_operand:SI 2 "arith_operand" "rI"))
4512 (match_operand:SI 3 "register_operand" "0")))]
4515 [(set_attr "type" "imul")])
4517 (define_insn "*smacdi"
4518 [(set (match_operand:DI 0 "register_operand" "=r")
4519 (plus:DI (mult:DI (sign_extend:DI
4520 (match_operand:SI 1 "register_operand" "%r"))
4522 (match_operand:SI 2 "register_operand" "r")))
4523 (match_operand:DI 3 "register_operand" "0")))]
4525 "smacd\t%1, %2, %L0"
4526 [(set_attr "type" "imul")])
4528 (define_insn "*umacdi"
4529 [(set (match_operand:DI 0 "register_operand" "=r")
4530 (plus:DI (mult:DI (zero_extend:DI
4531 (match_operand:SI 1 "register_operand" "%r"))
4533 (match_operand:SI 2 "register_operand" "r")))
4534 (match_operand:DI 3 "register_operand" "0")))]
4536 "umacd\t%1, %2, %L0"
4537 [(set_attr "type" "imul")])
4540 ;; Boolean instructions.
4542 ;; We define DImode `and' so with DImode `not' we can get
4543 ;; DImode `andn'. Other combinations are possible.
4545 (define_expand "and<V64I:mode>3"
4546 [(set (match_operand:V64I 0 "register_operand" "")
4547 (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
4548 (match_operand:V64I 2 "arith_double_operand" "")))]
4552 (define_insn "*and<V64I:mode>3_sp32"
4553 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4554 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4555 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4560 [(set_attr "type" "*,fga")
4561 (set_attr "length" "2,*")
4562 (set_attr "fptype" "*,double")])
4564 (define_insn "*and<V64I:mode>3_sp64"
4565 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4566 (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4567 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4572 [(set_attr "type" "*,fga")
4573 (set_attr "fptype" "*,double")])
4575 (define_insn "and<V32I:mode>3"
4576 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4577 (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4578 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4583 [(set_attr "type" "*,fga")
4584 (set_attr "fptype" "*,single")])
4587 [(set (match_operand:SI 0 "register_operand" "")
4588 (and:SI (match_operand:SI 1 "register_operand" "")
4589 (match_operand:SI 2 "const_compl_high_operand" "")))
4590 (clobber (match_operand:SI 3 "register_operand" ""))]
4592 [(set (match_dup 3) (match_dup 4))
4593 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
4595 operands[4] = GEN_INT (~INTVAL (operands[2]));
4598 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
4599 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4600 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4601 (match_operand:V64I 2 "register_operand" "r,b")))]
4605 fandnot1\t%1, %2, %0"
4606 "&& reload_completed
4607 && ((GET_CODE (operands[0]) == REG
4608 && REGNO (operands[0]) < 32)
4609 || (GET_CODE (operands[0]) == SUBREG
4610 && GET_CODE (SUBREG_REG (operands[0])) == REG
4611 && REGNO (SUBREG_REG (operands[0])) < 32))"
4612 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
4613 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
4614 "operands[3] = gen_highpart (SImode, operands[0]);
4615 operands[4] = gen_highpart (SImode, operands[1]);
4616 operands[5] = gen_highpart (SImode, operands[2]);
4617 operands[6] = gen_lowpart (SImode, operands[0]);
4618 operands[7] = gen_lowpart (SImode, operands[1]);
4619 operands[8] = gen_lowpart (SImode, operands[2]);"
4620 [(set_attr "type" "*,fga")
4621 (set_attr "length" "2,*")
4622 (set_attr "fptype" "*,double")])
4624 (define_insn "*and_not_<V64I:mode>_sp64"
4625 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4626 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4627 (match_operand:V64I 2 "register_operand" "r,b")))]
4631 fandnot1\t%1, %2, %0"
4632 [(set_attr "type" "*,fga")
4633 (set_attr "fptype" "*,double")])
4635 (define_insn "*and_not_<V32I:mode>"
4636 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4637 (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
4638 (match_operand:V32I 2 "register_operand" "r,d")))]
4642 fandnot1s\t%1, %2, %0"
4643 [(set_attr "type" "*,fga")
4644 (set_attr "fptype" "*,single")])
4646 (define_expand "ior<V64I:mode>3"
4647 [(set (match_operand:V64I 0 "register_operand" "")
4648 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
4649 (match_operand:V64I 2 "arith_double_operand" "")))]
4653 (define_insn "*ior<V64I:mode>3_sp32"
4654 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4655 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4656 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4661 [(set_attr "type" "*,fga")
4662 (set_attr "length" "2,*")
4663 (set_attr "fptype" "*,double")])
4665 (define_insn "*ior<V64I:mode>3_sp64"
4666 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4667 (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4668 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4673 [(set_attr "type" "*,fga")
4674 (set_attr "fptype" "*,double")])
4676 (define_insn "ior<V32I:mode>3"
4677 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4678 (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4679 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4684 [(set_attr "type" "*,fga")
4685 (set_attr "fptype" "*,single")])
4688 [(set (match_operand:SI 0 "register_operand" "")
4689 (ior:SI (match_operand:SI 1 "register_operand" "")
4690 (match_operand:SI 2 "const_compl_high_operand" "")))
4691 (clobber (match_operand:SI 3 "register_operand" ""))]
4693 [(set (match_dup 3) (match_dup 4))
4694 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4696 operands[4] = GEN_INT (~INTVAL (operands[2]));
4699 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
4700 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4701 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4702 (match_operand:V64I 2 "register_operand" "r,b")))]
4706 fornot1\t%1, %2, %0"
4707 "&& reload_completed
4708 && ((GET_CODE (operands[0]) == REG
4709 && REGNO (operands[0]) < 32)
4710 || (GET_CODE (operands[0]) == SUBREG
4711 && GET_CODE (SUBREG_REG (operands[0])) == REG
4712 && REGNO (SUBREG_REG (operands[0])) < 32))"
4713 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
4714 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
4715 "operands[3] = gen_highpart (SImode, operands[0]);
4716 operands[4] = gen_highpart (SImode, operands[1]);
4717 operands[5] = gen_highpart (SImode, operands[2]);
4718 operands[6] = gen_lowpart (SImode, operands[0]);
4719 operands[7] = gen_lowpart (SImode, operands[1]);
4720 operands[8] = gen_lowpart (SImode, operands[2]);"
4721 [(set_attr "type" "*,fga")
4722 (set_attr "length" "2,*")
4723 (set_attr "fptype" "*,double")])
4725 (define_insn "*or_not_<V64I:mode>_sp64"
4726 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4727 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4728 (match_operand:V64I 2 "register_operand" "r,b")))]
4732 fornot1\t%1, %2, %0"
4733 [(set_attr "type" "*,fga")
4734 (set_attr "fptype" "*,double")])
4736 (define_insn "*or_not_<V32I:mode>"
4737 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4738 (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
4739 (match_operand:V32I 2 "register_operand" "r,d")))]
4743 fornot1s\t%1, %2, %0"
4744 [(set_attr "type" "*,fga")
4745 (set_attr "fptype" "*,single")])
4747 (define_expand "xor<V64I:mode>3"
4748 [(set (match_operand:V64I 0 "register_operand" "")
4749 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
4750 (match_operand:V64I 2 "arith_double_operand" "")))]
4754 (define_insn "*xor<V64I:mode>3_sp32"
4755 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4756 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4757 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4762 [(set_attr "type" "*,fga")
4763 (set_attr "length" "2,*")
4764 (set_attr "fptype" "*,double")])
4766 (define_insn "*xor<V64I:mode>3_sp64"
4767 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4768 (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
4769 (match_operand:V64I 2 "arith_operand" "rI,b")))]
4774 [(set_attr "type" "*,fga")
4775 (set_attr "fptype" "*,double")])
4777 (define_insn "xor<V32I:mode>3"
4778 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4779 (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
4780 (match_operand:V32I 2 "arith_operand" "rI,d")))]
4785 [(set_attr "type" "*,fga")
4786 (set_attr "fptype" "*,single")])
4789 [(set (match_operand:SI 0 "register_operand" "")
4790 (xor:SI (match_operand:SI 1 "register_operand" "")
4791 (match_operand:SI 2 "const_compl_high_operand" "")))
4792 (clobber (match_operand:SI 3 "register_operand" ""))]
4794 [(set (match_dup 3) (match_dup 4))
4795 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4797 operands[4] = GEN_INT (~INTVAL (operands[2]));
4801 [(set (match_operand:SI 0 "register_operand" "")
4802 (not:SI (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) (xor:SI (match_dup 3) (match_dup 1)))]
4809 operands[4] = GEN_INT (~INTVAL (operands[2]));
4812 ;; Split DImode logical operations requiring two instructions.
4814 [(set (match_operand:V64I 0 "register_operand" "")
4815 (match_operator:V64I 1 "cc_arith_operator" ; AND, IOR, XOR
4816 [(match_operand:V64I 2 "register_operand" "")
4817 (match_operand:V64I 3 "arith_double_operand" "")]))]
4820 && ((GET_CODE (operands[0]) == REG
4821 && REGNO (operands[0]) < 32)
4822 || (GET_CODE (operands[0]) == SUBREG
4823 && GET_CODE (SUBREG_REG (operands[0])) == REG
4824 && REGNO (SUBREG_REG (operands[0])) < 32))"
4825 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
4826 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
4828 operands[4] = gen_highpart (SImode, operands[0]);
4829 operands[5] = gen_lowpart (SImode, operands[0]);
4830 operands[6] = gen_highpart (SImode, operands[2]);
4831 operands[7] = gen_lowpart (SImode, operands[2]);
4832 #if HOST_BITS_PER_WIDE_INT == 32
4833 if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
4835 if (INTVAL (operands[3]) < 0)
4836 operands[8] = constm1_rtx;
4838 operands[8] = const0_rtx;
4842 operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
4843 operands[9] = gen_lowpart (SImode, operands[3]);
4846 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
4847 ;; Combine now canonicalizes to the rightmost expression.
4848 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
4849 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4850 (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
4851 (match_operand:V64I 2 "register_operand" "r,b"))))]
4856 "&& reload_completed
4857 && ((GET_CODE (operands[0]) == REG
4858 && REGNO (operands[0]) < 32)
4859 || (GET_CODE (operands[0]) == SUBREG
4860 && GET_CODE (SUBREG_REG (operands[0])) == REG
4861 && REGNO (SUBREG_REG (operands[0])) < 32))"
4862 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
4863 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
4864 "operands[3] = gen_highpart (SImode, operands[0]);
4865 operands[4] = gen_highpart (SImode, operands[1]);
4866 operands[5] = gen_highpart (SImode, operands[2]);
4867 operands[6] = gen_lowpart (SImode, operands[0]);
4868 operands[7] = gen_lowpart (SImode, operands[1]);
4869 operands[8] = gen_lowpart (SImode, operands[2]);"
4870 [(set_attr "type" "*,fga")
4871 (set_attr "length" "2,*")
4872 (set_attr "fptype" "*,double")])
4874 (define_insn "*xor_not_<V64I:mode>_sp64"
4875 [(set (match_operand:V64I 0 "register_operand" "=r,b")
4876 (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
4877 (match_operand:V64I 2 "arith_operand" "rI,b"))))]
4882 [(set_attr "type" "*,fga")
4883 (set_attr "fptype" "*,double")])
4885 (define_insn "*xor_not_<V32I:mode>"
4886 [(set (match_operand:V32I 0 "register_operand" "=r,d")
4887 (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
4888 (match_operand:V32I 2 "arith_operand" "rI,d"))))]
4893 [(set_attr "type" "*,fga")
4894 (set_attr "fptype" "*,single")])
4896 ;; These correspond to the above in the case where we also (or only)
4897 ;; want to set the condition code.
4899 (define_insn "*cmp_cc_arith_op"
4902 (match_operator:SI 2 "cc_arith_operator"
4903 [(match_operand:SI 0 "arith_operand" "%r")
4904 (match_operand:SI 1 "arith_operand" "rI")])
4907 "%A2cc\t%0, %1, %%g0"
4908 [(set_attr "type" "compare")])
4910 (define_insn "*cmp_ccx_arith_op"
4913 (match_operator:DI 2 "cc_arith_operator"
4914 [(match_operand:DI 0 "arith_operand" "%r")
4915 (match_operand:DI 1 "arith_operand" "rI")])
4918 "%A2cc\t%0, %1, %%g0"
4919 [(set_attr "type" "compare")])
4921 (define_insn "*cmp_cc_arith_op_set"
4924 (match_operator:SI 3 "cc_arith_operator"
4925 [(match_operand:SI 1 "arith_operand" "%r")
4926 (match_operand:SI 2 "arith_operand" "rI")])
4928 (set (match_operand:SI 0 "register_operand" "=r")
4929 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
4930 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
4932 [(set_attr "type" "compare")])
4934 (define_insn "*cmp_ccx_arith_op_set"
4937 (match_operator:DI 3 "cc_arith_operator"
4938 [(match_operand:DI 1 "arith_operand" "%r")
4939 (match_operand:DI 2 "arith_operand" "rI")])
4941 (set (match_operand:DI 0 "register_operand" "=r")
4942 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
4943 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
4945 [(set_attr "type" "compare")])
4947 (define_insn "*cmp_cc_xor_not"
4950 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
4951 (match_operand:SI 1 "arith_operand" "rI")))
4954 "xnorcc\t%r0, %1, %%g0"
4955 [(set_attr "type" "compare")])
4957 (define_insn "*cmp_ccx_xor_not"
4960 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
4961 (match_operand:DI 1 "arith_operand" "rI")))
4964 "xnorcc\t%r0, %1, %%g0"
4965 [(set_attr "type" "compare")])
4967 (define_insn "*cmp_cc_xor_not_set"
4970 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4971 (match_operand:SI 2 "arith_operand" "rI")))
4973 (set (match_operand:SI 0 "register_operand" "=r")
4974 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
4976 "xnorcc\t%r1, %2, %0"
4977 [(set_attr "type" "compare")])
4979 (define_insn "*cmp_ccx_xor_not_set"
4982 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
4983 (match_operand:DI 2 "arith_operand" "rI")))
4985 (set (match_operand:DI 0 "register_operand" "=r")
4986 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
4988 "xnorcc\t%r1, %2, %0"
4989 [(set_attr "type" "compare")])
4991 (define_insn "*cmp_cc_arith_op_not"
4994 (match_operator:SI 2 "cc_arith_not_operator"
4995 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
4996 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
4999 "%B2cc\t%r1, %0, %%g0"
5000 [(set_attr "type" "compare")])
5002 (define_insn "*cmp_ccx_arith_op_not"
5005 (match_operator:DI 2 "cc_arith_not_operator"
5006 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5007 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5010 "%B2cc\t%r1, %0, %%g0"
5011 [(set_attr "type" "compare")])
5013 (define_insn "*cmp_cc_arith_op_not_set"
5016 (match_operator:SI 3 "cc_arith_not_operator"
5017 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5018 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5020 (set (match_operand:SI 0 "register_operand" "=r")
5021 (match_operator:SI 4 "cc_arith_not_operator"
5022 [(not:SI (match_dup 1)) (match_dup 2)]))]
5023 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5024 "%B3cc\t%r2, %1, %0"
5025 [(set_attr "type" "compare")])
5027 (define_insn "*cmp_ccx_arith_op_not_set"
5030 (match_operator:DI 3 "cc_arith_not_operator"
5031 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5032 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5034 (set (match_operand:DI 0 "register_operand" "=r")
5035 (match_operator:DI 4 "cc_arith_not_operator"
5036 [(not:DI (match_dup 1)) (match_dup 2)]))]
5037 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5038 "%B3cc\t%r2, %1, %0"
5039 [(set_attr "type" "compare")])
5041 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5042 ;; does not know how to make it work for constants.
5044 (define_expand "negdi2"
5045 [(set (match_operand:DI 0 "register_operand" "=r")
5046 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5049 if (! TARGET_ARCH64)
5051 emit_insn (gen_rtx_PARALLEL
5054 gen_rtx_SET (VOIDmode, operand0,
5055 gen_rtx_NEG (DImode, operand1)),
5056 gen_rtx_CLOBBER (VOIDmode,
5057 gen_rtx_REG (CCmode,
5063 (define_insn_and_split "*negdi2_sp32"
5064 [(set (match_operand:DI 0 "register_operand" "=r")
5065 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5066 (clobber (reg:CC 100))]
5069 "&& reload_completed"
5070 [(parallel [(set (reg:CC_NOOV 100)
5071 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5073 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5074 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5075 (ltu:SI (reg:CC 100) (const_int 0))))]
5076 "operands[2] = gen_highpart (SImode, operands[0]);
5077 operands[3] = gen_highpart (SImode, operands[1]);
5078 operands[4] = gen_lowpart (SImode, operands[0]);
5079 operands[5] = gen_lowpart (SImode, operands[1]);"
5080 [(set_attr "length" "2")])
5082 (define_insn "*negdi2_sp64"
5083 [(set (match_operand:DI 0 "register_operand" "=r")
5084 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5086 "sub\t%%g0, %1, %0")
5088 (define_insn "negsi2"
5089 [(set (match_operand:SI 0 "register_operand" "=r")
5090 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5092 "sub\t%%g0, %1, %0")
5094 (define_insn "*cmp_cc_neg"
5095 [(set (reg:CC_NOOV 100)
5096 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5099 "subcc\t%%g0, %0, %%g0"
5100 [(set_attr "type" "compare")])
5102 (define_insn "*cmp_ccx_neg"
5103 [(set (reg:CCX_NOOV 100)
5104 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5107 "subcc\t%%g0, %0, %%g0"
5108 [(set_attr "type" "compare")])
5110 (define_insn "*cmp_cc_set_neg"
5111 [(set (reg:CC_NOOV 100)
5112 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5114 (set (match_operand:SI 0 "register_operand" "=r")
5115 (neg:SI (match_dup 1)))]
5117 "subcc\t%%g0, %1, %0"
5118 [(set_attr "type" "compare")])
5120 (define_insn "*cmp_ccx_set_neg"
5121 [(set (reg:CCX_NOOV 100)
5122 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5124 (set (match_operand:DI 0 "register_operand" "=r")
5125 (neg:DI (match_dup 1)))]
5127 "subcc\t%%g0, %1, %0"
5128 [(set_attr "type" "compare")])
5130 ;; We cannot use the "not" pseudo insn because the Sun assembler
5131 ;; does not know how to make it work for constants.
5132 (define_expand "one_cmpl<V64I:mode>2"
5133 [(set (match_operand:V64I 0 "register_operand" "")
5134 (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5138 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5139 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5140 (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5145 "&& reload_completed
5146 && ((GET_CODE (operands[0]) == REG
5147 && REGNO (operands[0]) < 32)
5148 || (GET_CODE (operands[0]) == SUBREG
5149 && GET_CODE (SUBREG_REG (operands[0])) == REG
5150 && REGNO (SUBREG_REG (operands[0])) < 32))"
5151 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5152 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5153 "operands[2] = gen_highpart (SImode, operands[0]);
5154 operands[3] = gen_highpart (SImode, operands[1]);
5155 operands[4] = gen_lowpart (SImode, operands[0]);
5156 operands[5] = gen_lowpart (SImode, operands[1]);"
5157 [(set_attr "type" "*,fga")
5158 (set_attr "length" "2,*")
5159 (set_attr "fptype" "*,double")])
5161 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5162 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5163 (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5168 [(set_attr "type" "*,fga")
5169 (set_attr "fptype" "*,double")])
5171 (define_insn "one_cmpl<V32I:mode>2"
5172 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5173 (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5178 [(set_attr "type" "*,fga")
5179 (set_attr "fptype" "*,single")])
5181 (define_insn "*cmp_cc_not"
5183 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5186 "xnorcc\t%%g0, %0, %%g0"
5187 [(set_attr "type" "compare")])
5189 (define_insn "*cmp_ccx_not"
5191 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5194 "xnorcc\t%%g0, %0, %%g0"
5195 [(set_attr "type" "compare")])
5197 (define_insn "*cmp_cc_set_not"
5199 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5201 (set (match_operand:SI 0 "register_operand" "=r")
5202 (not:SI (match_dup 1)))]
5204 "xnorcc\t%%g0, %1, %0"
5205 [(set_attr "type" "compare")])
5207 (define_insn "*cmp_ccx_set_not"
5209 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5211 (set (match_operand:DI 0 "register_operand" "=r")
5212 (not:DI (match_dup 1)))]
5214 "xnorcc\t%%g0, %1, %0"
5215 [(set_attr "type" "compare")])
5217 (define_insn "*cmp_cc_set"
5218 [(set (match_operand:SI 0 "register_operand" "=r")
5219 (match_operand:SI 1 "register_operand" "r"))
5221 (compare:CC (match_dup 1)
5225 [(set_attr "type" "compare")])
5227 (define_insn "*cmp_ccx_set64"
5228 [(set (match_operand:DI 0 "register_operand" "=r")
5229 (match_operand:DI 1 "register_operand" "r"))
5231 (compare:CCX (match_dup 1)
5235 [(set_attr "type" "compare")])
5238 ;; Floating point arithmetic instructions.
5240 (define_expand "addtf3"
5241 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5242 (plus:TF (match_operand:TF 1 "general_operand" "")
5243 (match_operand:TF 2 "general_operand" "")))]
5244 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5245 "emit_tfmode_binop (PLUS, operands); DONE;")
5247 (define_insn "*addtf3_hq"
5248 [(set (match_operand:TF 0 "register_operand" "=e")
5249 (plus:TF (match_operand:TF 1 "register_operand" "e")
5250 (match_operand:TF 2 "register_operand" "e")))]
5251 "TARGET_FPU && TARGET_HARD_QUAD"
5253 [(set_attr "type" "fp")])
5255 (define_insn "adddf3"
5256 [(set (match_operand:DF 0 "register_operand" "=e")
5257 (plus:DF (match_operand:DF 1 "register_operand" "e")
5258 (match_operand:DF 2 "register_operand" "e")))]
5261 [(set_attr "type" "fp")
5262 (set_attr "fptype" "double")])
5264 (define_insn "addsf3"
5265 [(set (match_operand:SF 0 "register_operand" "=f")
5266 (plus:SF (match_operand:SF 1 "register_operand" "f")
5267 (match_operand:SF 2 "register_operand" "f")))]
5270 [(set_attr "type" "fp")])
5272 (define_expand "subtf3"
5273 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5274 (minus:TF (match_operand:TF 1 "general_operand" "")
5275 (match_operand:TF 2 "general_operand" "")))]
5276 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5277 "emit_tfmode_binop (MINUS, operands); DONE;")
5279 (define_insn "*subtf3_hq"
5280 [(set (match_operand:TF 0 "register_operand" "=e")
5281 (minus:TF (match_operand:TF 1 "register_operand" "e")
5282 (match_operand:TF 2 "register_operand" "e")))]
5283 "TARGET_FPU && TARGET_HARD_QUAD"
5285 [(set_attr "type" "fp")])
5287 (define_insn "subdf3"
5288 [(set (match_operand:DF 0 "register_operand" "=e")
5289 (minus:DF (match_operand:DF 1 "register_operand" "e")
5290 (match_operand:DF 2 "register_operand" "e")))]
5293 [(set_attr "type" "fp")
5294 (set_attr "fptype" "double")])
5296 (define_insn "subsf3"
5297 [(set (match_operand:SF 0 "register_operand" "=f")
5298 (minus:SF (match_operand:SF 1 "register_operand" "f")
5299 (match_operand:SF 2 "register_operand" "f")))]
5302 [(set_attr "type" "fp")])
5304 (define_expand "multf3"
5305 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5306 (mult:TF (match_operand:TF 1 "general_operand" "")
5307 (match_operand:TF 2 "general_operand" "")))]
5308 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5309 "emit_tfmode_binop (MULT, operands); DONE;")
5311 (define_insn "*multf3_hq"
5312 [(set (match_operand:TF 0 "register_operand" "=e")
5313 (mult:TF (match_operand:TF 1 "register_operand" "e")
5314 (match_operand:TF 2 "register_operand" "e")))]
5315 "TARGET_FPU && TARGET_HARD_QUAD"
5317 [(set_attr "type" "fpmul")])
5319 (define_insn "muldf3"
5320 [(set (match_operand:DF 0 "register_operand" "=e")
5321 (mult:DF (match_operand:DF 1 "register_operand" "e")
5322 (match_operand:DF 2 "register_operand" "e")))]
5325 [(set_attr "type" "fpmul")
5326 (set_attr "fptype" "double")])
5328 (define_insn "mulsf3"
5329 [(set (match_operand:SF 0 "register_operand" "=f")
5330 (mult:SF (match_operand:SF 1 "register_operand" "f")
5331 (match_operand:SF 2 "register_operand" "f")))]
5334 [(set_attr "type" "fpmul")])
5336 (define_insn "*muldf3_extend"
5337 [(set (match_operand:DF 0 "register_operand" "=e")
5338 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5339 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5340 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
5341 "fsmuld\t%1, %2, %0"
5342 [(set_attr "type" "fpmul")
5343 (set_attr "fptype" "double")])
5345 (define_insn "*multf3_extend"
5346 [(set (match_operand:TF 0 "register_operand" "=e")
5347 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5348 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5349 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5350 "fdmulq\t%1, %2, %0"
5351 [(set_attr "type" "fpmul")])
5353 (define_expand "divtf3"
5354 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5355 (div:TF (match_operand:TF 1 "general_operand" "")
5356 (match_operand:TF 2 "general_operand" "")))]
5357 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5358 "emit_tfmode_binop (DIV, operands); DONE;")
5360 ;; don't have timing for quad-prec. divide.
5361 (define_insn "*divtf3_hq"
5362 [(set (match_operand:TF 0 "register_operand" "=e")
5363 (div:TF (match_operand:TF 1 "register_operand" "e")
5364 (match_operand:TF 2 "register_operand" "e")))]
5365 "TARGET_FPU && TARGET_HARD_QUAD"
5367 [(set_attr "type" "fpdivd")])
5369 (define_insn "divdf3"
5370 [(set (match_operand:DF 0 "register_operand" "=e")
5371 (div:DF (match_operand:DF 1 "register_operand" "e")
5372 (match_operand:DF 2 "register_operand" "e")))]
5375 [(set_attr "type" "fpdivd")
5376 (set_attr "fptype" "double")])
5378 (define_insn "divsf3"
5379 [(set (match_operand:SF 0 "register_operand" "=f")
5380 (div:SF (match_operand:SF 1 "register_operand" "f")
5381 (match_operand:SF 2 "register_operand" "f")))]
5384 [(set_attr "type" "fpdivs")])
5386 (define_expand "negtf2"
5387 [(set (match_operand:TF 0 "register_operand" "=e,e")
5388 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5392 (define_insn_and_split "*negtf2_notv9"
5393 [(set (match_operand:TF 0 "register_operand" "=e,e")
5394 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5395 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5401 "&& reload_completed
5402 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5403 [(set (match_dup 2) (neg:SF (match_dup 3)))
5404 (set (match_dup 4) (match_dup 5))
5405 (set (match_dup 6) (match_dup 7))]
5406 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5407 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5408 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5409 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5410 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5411 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5412 [(set_attr "type" "fpmove,*")
5413 (set_attr "length" "*,2")])
5415 (define_insn_and_split "*negtf2_v9"
5416 [(set (match_operand:TF 0 "register_operand" "=e,e")
5417 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5418 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5419 "TARGET_FPU && TARGET_V9"
5423 "&& reload_completed
5424 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5425 [(set (match_dup 2) (neg:DF (match_dup 3)))
5426 (set (match_dup 4) (match_dup 5))]
5427 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5428 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5429 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5430 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5431 [(set_attr "type" "fpmove,*")
5432 (set_attr "length" "*,2")
5433 (set_attr "fptype" "double")])
5435 (define_expand "negdf2"
5436 [(set (match_operand:DF 0 "register_operand" "")
5437 (neg:DF (match_operand:DF 1 "register_operand" "")))]
5441 (define_insn_and_split "*negdf2_notv9"
5442 [(set (match_operand:DF 0 "register_operand" "=e,e")
5443 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
5444 "TARGET_FPU && ! TARGET_V9"
5448 "&& reload_completed
5449 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5450 [(set (match_dup 2) (neg:SF (match_dup 3)))
5451 (set (match_dup 4) (match_dup 5))]
5452 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5453 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5454 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5455 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5456 [(set_attr "type" "fpmove,*")
5457 (set_attr "length" "*,2")])
5459 (define_insn "*negdf2_v9"
5460 [(set (match_operand:DF 0 "register_operand" "=e")
5461 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5462 "TARGET_FPU && TARGET_V9"
5464 [(set_attr "type" "fpmove")
5465 (set_attr "fptype" "double")])
5467 (define_insn "negsf2"
5468 [(set (match_operand:SF 0 "register_operand" "=f")
5469 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
5472 [(set_attr "type" "fpmove")])
5474 (define_expand "abstf2"
5475 [(set (match_operand:TF 0 "register_operand" "")
5476 (abs:TF (match_operand:TF 1 "register_operand" "")))]
5480 (define_insn_and_split "*abstf2_notv9"
5481 [(set (match_operand:TF 0 "register_operand" "=e,e")
5482 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5483 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5484 "TARGET_FPU && ! TARGET_V9"
5488 "&& reload_completed
5489 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5490 [(set (match_dup 2) (abs:SF (match_dup 3)))
5491 (set (match_dup 4) (match_dup 5))
5492 (set (match_dup 6) (match_dup 7))]
5493 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5494 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5495 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5496 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5497 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5498 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5499 [(set_attr "type" "fpmove,*")
5500 (set_attr "length" "*,2")])
5502 (define_insn "*abstf2_hq_v9"
5503 [(set (match_operand:TF 0 "register_operand" "=e,e")
5504 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5505 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
5509 [(set_attr "type" "fpmove")
5510 (set_attr "fptype" "double,*")])
5512 (define_insn_and_split "*abstf2_v9"
5513 [(set (match_operand:TF 0 "register_operand" "=e,e")
5514 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5515 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
5519 "&& reload_completed
5520 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5521 [(set (match_dup 2) (abs:DF (match_dup 3)))
5522 (set (match_dup 4) (match_dup 5))]
5523 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5524 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5525 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5526 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5527 [(set_attr "type" "fpmove,*")
5528 (set_attr "length" "*,2")
5529 (set_attr "fptype" "double,*")])
5531 (define_expand "absdf2"
5532 [(set (match_operand:DF 0 "register_operand" "")
5533 (abs:DF (match_operand:DF 1 "register_operand" "")))]
5537 (define_insn_and_split "*absdf2_notv9"
5538 [(set (match_operand:DF 0 "register_operand" "=e,e")
5539 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
5540 "TARGET_FPU && ! TARGET_V9"
5544 "&& reload_completed
5545 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5546 [(set (match_dup 2) (abs:SF (match_dup 3)))
5547 (set (match_dup 4) (match_dup 5))]
5548 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5549 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5550 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5551 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5552 [(set_attr "type" "fpmove,*")
5553 (set_attr "length" "*,2")])
5555 (define_insn "*absdf2_v9"
5556 [(set (match_operand:DF 0 "register_operand" "=e")
5557 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5558 "TARGET_FPU && TARGET_V9"
5560 [(set_attr "type" "fpmove")
5561 (set_attr "fptype" "double")])
5563 (define_insn "abssf2"
5564 [(set (match_operand:SF 0 "register_operand" "=f")
5565 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
5568 [(set_attr "type" "fpmove")])
5570 (define_expand "sqrttf2"
5571 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5572 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
5573 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5574 "emit_tfmode_unop (SQRT, operands); DONE;")
5576 (define_insn "*sqrttf2_hq"
5577 [(set (match_operand:TF 0 "register_operand" "=e")
5578 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
5579 "TARGET_FPU && TARGET_HARD_QUAD"
5581 [(set_attr "type" "fpsqrtd")])
5583 (define_insn "sqrtdf2"
5584 [(set (match_operand:DF 0 "register_operand" "=e")
5585 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5588 [(set_attr "type" "fpsqrtd")
5589 (set_attr "fptype" "double")])
5591 (define_insn "sqrtsf2"
5592 [(set (match_operand:SF 0 "register_operand" "=f")
5593 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
5596 [(set_attr "type" "fpsqrts")])
5599 ;; Arithmetic shift instructions.
5601 (define_insn "ashlsi3"
5602 [(set (match_operand:SI 0 "register_operand" "=r")
5603 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5604 (match_operand:SI 2 "arith_operand" "rI")))]
5607 if (GET_CODE (operands[2]) == CONST_INT)
5608 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5609 return "sll\t%1, %2, %0";
5612 (if_then_else (match_operand 2 "const_one_operand" "")
5613 (const_string "ialu") (const_string "shift")))])
5615 (define_expand "ashldi3"
5616 [(set (match_operand:DI 0 "register_operand" "=r")
5617 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5618 (match_operand:SI 2 "arith_operand" "rI")))]
5619 "TARGET_ARCH64 || TARGET_V8PLUS"
5621 if (! TARGET_ARCH64)
5623 if (GET_CODE (operands[2]) == CONST_INT)
5625 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
5630 (define_insn "*ashldi3_sp64"
5631 [(set (match_operand:DI 0 "register_operand" "=r")
5632 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5633 (match_operand:SI 2 "arith_operand" "rI")))]
5636 if (GET_CODE (operands[2]) == CONST_INT)
5637 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5638 return "sllx\t%1, %2, %0";
5641 (if_then_else (match_operand 2 "const_one_operand" "")
5642 (const_string "ialu") (const_string "shift")))])
5645 (define_insn "ashldi3_v8plus"
5646 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5647 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5648 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5649 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5651 "* return output_v8plus_shift (operands, insn, \"sllx\");"
5652 [(set_attr "type" "multi")
5653 (set_attr "length" "5,5,6")])
5655 ;; Optimize (1LL<<x)-1
5656 ;; XXX this also needs to be fixed to handle equal subregs
5657 ;; XXX first before we could re-enable it.
5659 ; [(set (match_operand:DI 0 "register_operand" "=h")
5660 ; (plus:DI (ashift:DI (const_int 1)
5661 ; (match_operand:SI 1 "arith_operand" "rI"))
5663 ; "0 && TARGET_V8PLUS"
5665 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
5666 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5667 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5669 ; [(set_attr "type" "multi")
5670 ; (set_attr "length" "4")])
5672 (define_insn "*cmp_cc_ashift_1"
5673 [(set (reg:CC_NOOV 100)
5674 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
5678 "addcc\t%0, %0, %%g0"
5679 [(set_attr "type" "compare")])
5681 (define_insn "*cmp_cc_set_ashift_1"
5682 [(set (reg:CC_NOOV 100)
5683 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
5686 (set (match_operand:SI 0 "register_operand" "=r")
5687 (ashift:SI (match_dup 1) (const_int 1)))]
5690 [(set_attr "type" "compare")])
5692 (define_insn "ashrsi3"
5693 [(set (match_operand:SI 0 "register_operand" "=r")
5694 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5695 (match_operand:SI 2 "arith_operand" "rI")))]
5698 if (GET_CODE (operands[2]) == CONST_INT)
5699 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5700 return "sra\t%1, %2, %0";
5702 [(set_attr "type" "shift")])
5704 (define_insn "*ashrsi3_extend"
5705 [(set (match_operand:DI 0 "register_operand" "=r")
5706 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5707 (match_operand:SI 2 "arith_operand" "r"))))]
5710 [(set_attr "type" "shift")])
5712 ;; This handles the case as above, but with constant shift instead of
5713 ;; register. Combiner "simplifies" it for us a little bit though.
5714 (define_insn "*ashrsi3_extend2"
5715 [(set (match_operand:DI 0 "register_operand" "=r")
5716 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5718 (match_operand:SI 2 "small_int_operand" "I")))]
5719 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
5721 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5722 return "sra\t%1, %2, %0";
5724 [(set_attr "type" "shift")])
5726 (define_expand "ashrdi3"
5727 [(set (match_operand:DI 0 "register_operand" "=r")
5728 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5729 (match_operand:SI 2 "arith_operand" "rI")))]
5730 "TARGET_ARCH64 || TARGET_V8PLUS"
5732 if (! TARGET_ARCH64)
5734 if (GET_CODE (operands[2]) == CONST_INT)
5735 FAIL; /* prefer generic code in this case */
5736 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
5741 (define_insn "*ashrdi3_sp64"
5742 [(set (match_operand:DI 0 "register_operand" "=r")
5743 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5744 (match_operand:SI 2 "arith_operand" "rI")))]
5748 if (GET_CODE (operands[2]) == CONST_INT)
5749 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5750 return "srax\t%1, %2, %0";
5752 [(set_attr "type" "shift")])
5755 (define_insn "ashrdi3_v8plus"
5756 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5757 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5758 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5759 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5761 "* return output_v8plus_shift (operands, insn, \"srax\");"
5762 [(set_attr "type" "multi")
5763 (set_attr "length" "5,5,6")])
5765 (define_insn "lshrsi3"
5766 [(set (match_operand:SI 0 "register_operand" "=r")
5767 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5768 (match_operand:SI 2 "arith_operand" "rI")))]
5771 if (GET_CODE (operands[2]) == CONST_INT)
5772 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5773 return "srl\t%1, %2, %0";
5775 [(set_attr "type" "shift")])
5777 ;; This handles the case where
5778 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
5779 ;; but combiner "simplifies" it for us.
5780 (define_insn "*lshrsi3_extend"
5781 [(set (match_operand:DI 0 "register_operand" "=r")
5782 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5783 (match_operand:SI 2 "arith_operand" "r")) 0)
5784 (match_operand 3 "const_int_operand" "")))]
5785 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
5787 [(set_attr "type" "shift")])
5789 ;; This handles the case where
5790 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
5791 ;; but combiner "simplifies" it for us.
5792 (define_insn "*lshrsi3_extend2"
5793 [(set (match_operand:DI 0 "register_operand" "=r")
5794 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5795 (match_operand 2 "small_int_operand" "I")
5797 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5799 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
5800 return "srl\t%1, %2, %0";
5802 [(set_attr "type" "shift")])
5804 (define_expand "lshrdi3"
5805 [(set (match_operand:DI 0 "register_operand" "=r")
5806 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5807 (match_operand:SI 2 "arith_operand" "rI")))]
5808 "TARGET_ARCH64 || TARGET_V8PLUS"
5810 if (! TARGET_ARCH64)
5812 if (GET_CODE (operands[2]) == CONST_INT)
5814 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
5819 (define_insn "*lshrdi3_sp64"
5820 [(set (match_operand:DI 0 "register_operand" "=r")
5821 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5822 (match_operand:SI 2 "arith_operand" "rI")))]
5825 if (GET_CODE (operands[2]) == CONST_INT)
5826 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5827 return "srlx\t%1, %2, %0";
5829 [(set_attr "type" "shift")])
5832 (define_insn "lshrdi3_v8plus"
5833 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5834 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5835 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5836 (clobber (match_scratch:SI 3 "=X,X,&h"))]
5838 "* return output_v8plus_shift (operands, insn, \"srlx\");"
5839 [(set_attr "type" "multi")
5840 (set_attr "length" "5,5,6")])
5843 [(set (match_operand:SI 0 "register_operand" "=r")
5844 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5846 (match_operand:SI 2 "small_int_operand" "I")))]
5847 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5849 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
5850 return "srax\t%1, %2, %0";
5852 [(set_attr "type" "shift")])
5855 [(set (match_operand:SI 0 "register_operand" "=r")
5856 (lshiftrt:SI (subreg:SI (ashiftrt: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 "srlx\t%1, %2, %0";
5864 [(set_attr "type" "shift")])
5867 [(set (match_operand:SI 0 "register_operand" "=r")
5868 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5869 (match_operand:SI 2 "small_int_operand" "I")) 4)
5870 (match_operand:SI 3 "small_int_operand" "I")))]
5872 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
5873 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
5874 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
5876 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
5878 return "srax\t%1, %2, %0";
5880 [(set_attr "type" "shift")])
5883 [(set (match_operand:SI 0 "register_operand" "=r")
5884 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5885 (match_operand:SI 2 "small_int_operand" "I")) 4)
5886 (match_operand:SI 3 "small_int_operand" "I")))]
5888 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
5889 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
5890 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
5892 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
5894 return "srlx\t%1, %2, %0";
5896 [(set_attr "type" "shift")])
5899 ;; Unconditional and other jump instructions.
5902 [(set (pc) (label_ref (match_operand 0 "" "")))]
5904 "* return output_ubranch (operands[0], 0, insn);"
5905 [(set_attr "type" "uncond_branch")])
5907 (define_expand "tablejump"
5908 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
5909 (use (label_ref (match_operand 1 "" "")))])]
5912 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
5914 /* In pic mode, our address differences are against the base of the
5915 table. Add that base value back in; CSE ought to be able to combine
5916 the two address loads. */
5920 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
5922 if (CASE_VECTOR_MODE != Pmode)
5923 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
5924 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
5925 operands[0] = memory_address (Pmode, tmp);
5929 (define_insn "*tablejump_sp32"
5930 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
5931 (use (label_ref (match_operand 1 "" "")))]
5934 [(set_attr "type" "uncond_branch")])
5936 (define_insn "*tablejump_sp64"
5937 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
5938 (use (label_ref (match_operand 1 "" "")))]
5941 [(set_attr "type" "uncond_branch")])
5944 ;; Jump to subroutine instructions.
5946 (define_expand "call"
5947 ;; Note that this expression is not used for generating RTL.
5948 ;; All the RTL is generated explicitly below.
5949 [(call (match_operand 0 "call_operand" "")
5950 (match_operand 3 "" "i"))]
5951 ;; operands[2] is next_arg_register
5952 ;; operands[3] is struct_value_size_rtx.
5957 gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
5959 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
5961 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
5963 /* This is really a PIC sequence. We want to represent
5964 it as a funny jump so its delay slots can be filled.
5966 ??? But if this really *is* a CALL, will not it clobber the
5967 call-clobbered registers? We lose this if it is a JUMP_INSN.
5968 Why cannot we have delay slots filled if it were a CALL? */
5970 /* We accept negative sizes for untyped calls. */
5971 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
5976 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
5978 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
5984 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
5985 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
5989 fn_rtx = operands[0];
5991 /* We accept negative sizes for untyped calls. */
5992 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
5993 sparc_emit_call_insn
5996 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
5998 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6001 sparc_emit_call_insn
6004 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6005 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6013 ;; We can't use the same pattern for these two insns, because then registers
6014 ;; in the address may not be properly reloaded.
6016 (define_insn "*call_address_sp32"
6017 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6018 (match_operand 1 "" ""))
6019 (clobber (reg:SI 15))]
6020 ;;- Do not use operand 1 for most machines.
6023 [(set_attr "type" "call")])
6025 (define_insn "*call_symbolic_sp32"
6026 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6027 (match_operand 1 "" ""))
6028 (clobber (reg:SI 15))]
6029 ;;- Do not use operand 1 for most machines.
6032 [(set_attr "type" "call")])
6034 (define_insn "*call_address_sp64"
6035 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6036 (match_operand 1 "" ""))
6037 (clobber (reg:DI 15))]
6038 ;;- Do not use operand 1 for most machines.
6041 [(set_attr "type" "call")])
6043 (define_insn "*call_symbolic_sp64"
6044 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6045 (match_operand 1 "" ""))
6046 (clobber (reg:DI 15))]
6047 ;;- Do not use operand 1 for most machines.
6050 [(set_attr "type" "call")])
6052 ;; This is a call that wants a structure value.
6053 ;; There is no such critter for v9 (??? we may need one anyway).
6054 (define_insn "*call_address_struct_value_sp32"
6055 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6056 (match_operand 1 "" ""))
6057 (match_operand 2 "immediate_operand" "")
6058 (clobber (reg:SI 15))]
6059 ;;- Do not use operand 1 for most machines.
6060 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6062 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6063 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6065 [(set_attr "type" "call_no_delay_slot")
6066 (set_attr "length" "3")])
6068 ;; This is a call that wants a structure value.
6069 ;; There is no such critter for v9 (??? we may need one anyway).
6070 (define_insn "*call_symbolic_struct_value_sp32"
6071 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6072 (match_operand 1 "" ""))
6073 (match_operand 2 "immediate_operand" "")
6074 (clobber (reg:SI 15))]
6075 ;;- Do not use operand 1 for most machines.
6076 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6078 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6079 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6081 [(set_attr "type" "call_no_delay_slot")
6082 (set_attr "length" "3")])
6084 ;; This is a call that may want a structure value. This is used for
6086 (define_insn "*call_address_untyped_struct_value_sp32"
6087 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6088 (match_operand 1 "" ""))
6089 (match_operand 2 "immediate_operand" "")
6090 (clobber (reg:SI 15))]
6091 ;;- Do not use operand 1 for most machines.
6092 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6093 "call\t%a0, %1\n\t nop\n\tnop"
6094 [(set_attr "type" "call_no_delay_slot")
6095 (set_attr "length" "3")])
6097 ;; This is a call that may want a structure value. This is used for
6099 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6100 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6101 (match_operand 1 "" ""))
6102 (match_operand 2 "immediate_operand" "")
6103 (clobber (reg:SI 15))]
6104 ;;- Do not use operand 1 for most machines.
6105 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6106 "call\t%a0, %1\n\t nop\n\tnop"
6107 [(set_attr "type" "call_no_delay_slot")
6108 (set_attr "length" "3")])
6110 (define_expand "call_value"
6111 ;; Note that this expression is not used for generating RTL.
6112 ;; All the RTL is generated explicitly below.
6113 [(set (match_operand 0 "register_operand" "=rf")
6114 (call (match_operand 1 "" "")
6115 (match_operand 4 "" "")))]
6116 ;; operand 2 is stack_size_rtx
6117 ;; operand 3 is next_arg_register
6123 gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6125 fn_rtx = operands[1];
6128 gen_rtx_SET (VOIDmode, operands[0],
6129 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6130 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6132 sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6137 (define_insn "*call_value_address_sp32"
6138 [(set (match_operand 0 "" "=rf")
6139 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6140 (match_operand 2 "" "")))
6141 (clobber (reg:SI 15))]
6142 ;;- Do not use operand 2 for most machines.
6145 [(set_attr "type" "call")])
6147 (define_insn "*call_value_symbolic_sp32"
6148 [(set (match_operand 0 "" "=rf")
6149 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6150 (match_operand 2 "" "")))
6151 (clobber (reg:SI 15))]
6152 ;;- Do not use operand 2 for most machines.
6155 [(set_attr "type" "call")])
6157 (define_insn "*call_value_address_sp64"
6158 [(set (match_operand 0 "" "")
6159 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6160 (match_operand 2 "" "")))
6161 (clobber (reg:DI 15))]
6162 ;;- Do not use operand 2 for most machines.
6165 [(set_attr "type" "call")])
6167 (define_insn "*call_value_symbolic_sp64"
6168 [(set (match_operand 0 "" "")
6169 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6170 (match_operand 2 "" "")))
6171 (clobber (reg:DI 15))]
6172 ;;- Do not use operand 2 for most machines.
6175 [(set_attr "type" "call")])
6177 (define_expand "untyped_call"
6178 [(parallel [(call (match_operand 0 "" "")
6180 (match_operand:BLK 1 "memory_operand" "")
6181 (match_operand 2 "" "")])]
6184 rtx valreg1 = gen_rtx_REG (DImode, 8);
6185 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6186 rtx result = operands[1];
6188 /* Pass constm1 to indicate that it may expect a structure value, but
6189 we don't know what size it is. */
6190 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6192 /* Save the function value registers. */
6193 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6194 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6197 /* The optimizer does not know that the call sets the function value
6198 registers we stored in the result block. We avoid problems by
6199 claiming that all hard registers are used and clobbered at this
6201 emit_insn (gen_blockage ());
6206 ;; Tail call instructions.
6208 (define_expand "sibcall"
6209 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6214 (define_insn "*sibcall_symbolic_sp32"
6215 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6216 (match_operand 1 "" ""))
6219 "* return output_sibcall(insn, operands[0]);"
6220 [(set_attr "type" "sibcall")])
6222 (define_insn "*sibcall_symbolic_sp64"
6223 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6224 (match_operand 1 "" ""))
6227 "* return output_sibcall(insn, operands[0]);"
6228 [(set_attr "type" "sibcall")])
6230 (define_expand "sibcall_value"
6231 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6232 (call (match_operand 1 "" "") (const_int 0)))
6237 (define_insn "*sibcall_value_symbolic_sp32"
6238 [(set (match_operand 0 "" "=rf")
6239 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6240 (match_operand 2 "" "")))
6243 "* return output_sibcall(insn, operands[1]);"
6244 [(set_attr "type" "sibcall")])
6246 (define_insn "*sibcall_value_symbolic_sp64"
6247 [(set (match_operand 0 "" "")
6248 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6249 (match_operand 2 "" "")))
6252 "* return output_sibcall(insn, operands[1]);"
6253 [(set_attr "type" "sibcall")])
6256 ;; Special instructions.
6258 (define_expand "prologue"
6262 sparc_expand_prologue ();
6266 ;; The "save register window" insn is modelled as follows so that the DWARF-2
6267 ;; backend automatically emits the required call frame debugging information
6268 ;; while it is parsing it. Therefore, the pattern should not be modified
6269 ;; without first studying the impact of the changes on the debug info.
6270 ;; [(set (%fp) (%sp))
6271 ;; (set (%sp) (unspec_volatile [(%sp) (-frame_size)] UNSPECV_SAVEW))
6272 ;; (set (%i7) (%o7))]
6274 (define_insn "save_register_window<P:mode>"
6275 [(set (reg:P 30) (reg:P 14))
6276 (set (reg:P 14) (unspec_volatile:P [(reg:P 14)
6277 (match_operand:P 0 "arith_operand" "rI")] UNSPECV_SAVEW))
6278 (set (reg:P 31) (reg:P 15))]
6280 "save\t%%sp, %0, %%sp"
6281 [(set_attr "type" "savew")])
6283 (define_expand "epilogue"
6287 sparc_expand_epilogue ();
6290 (define_expand "sibcall_epilogue"
6294 sparc_expand_epilogue ();
6298 (define_expand "return"
6300 "sparc_can_use_return_insn_p ()"
6303 (define_insn "*return_internal"
6306 "* return output_return (insn);"
6307 [(set_attr "type" "return")
6308 (set (attr "length")
6309 (cond [(eq_attr "leaf_function" "true")
6310 (if_then_else (eq_attr "empty_delay_slot" "true")
6313 (eq_attr "calls_eh_return" "true")
6314 (if_then_else (eq_attr "delayed_branch" "true")
6315 (if_then_else (eq_attr "isa" "v9")
6318 (if_then_else (eq_attr "isa" "v9")
6321 (eq_attr "empty_delay_slot" "true")
6322 (if_then_else (eq_attr "delayed_branch" "true")
6327 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6328 ;; all of memory. This blocks insns from being moved across this point.
6330 (define_insn "blockage"
6331 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6334 [(set_attr "length" "0")])
6336 (define_expand "probe_stack"
6337 [(set (match_operand 0 "memory_operand" "") (const_int 0))]
6341 = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
6344 (define_insn "probe_stack_range<P:mode>"
6345 [(set (match_operand:P 0 "register_operand" "=r")
6346 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6347 (match_operand:P 2 "register_operand" "r")]
6348 UNSPECV_PROBE_STACK_RANGE))]
6350 "* return output_probe_stack_range (operands[0], operands[2]);"
6351 [(set_attr "type" "multi")])
6353 ;; Prepare to return any type including a structure value.
6355 (define_expand "untyped_return"
6356 [(match_operand:BLK 0 "memory_operand" "")
6357 (match_operand 1 "" "")]
6360 rtx valreg1 = gen_rtx_REG (DImode, 24);
6361 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6362 rtx result = operands[0];
6364 if (! TARGET_ARCH64)
6366 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
6368 rtx value = gen_reg_rtx (SImode);
6370 /* Fetch the instruction where we will return to and see if it's an unimp
6371 instruction (the most significant 10 bits will be zero). If so,
6372 update the return address to skip the unimp instruction. */
6373 emit_move_insn (value,
6374 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
6375 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6376 emit_insn (gen_update_return (rtnreg, value));
6379 /* Reload the function value registers. */
6380 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6381 emit_move_insn (valreg2,
6382 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6384 /* Put USE insns before the return. */
6388 /* Construct the return. */
6389 expand_naked_return ();
6394 ;; Adjust the return address conditionally. If the value of op1 is equal
6395 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6396 ;; This is technically *half* the check required by the 32-bit SPARC
6397 ;; psABI. This check only ensures that an "unimp" insn was written by
6398 ;; the caller, but doesn't check to see if the expected size matches
6399 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6400 ;; only used by the above code "untyped_return".
6402 (define_insn "update_return"
6403 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6404 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6407 if (flag_delayed_branch)
6408 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6410 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6412 [(set (attr "type") (const_string "multi"))
6413 (set (attr "length")
6414 (if_then_else (eq_attr "delayed_branch" "true")
6423 (define_expand "indirect_jump"
6424 [(set (pc) (match_operand 0 "address_operand" "p"))]
6428 (define_insn "*branch_sp32"
6429 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6432 [(set_attr "type" "uncond_branch")])
6434 (define_insn "*branch_sp64"
6435 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6438 [(set_attr "type" "uncond_branch")])
6440 (define_expand "nonlocal_goto"
6441 [(match_operand:SI 0 "general_operand" "")
6442 (match_operand:SI 1 "general_operand" "")
6443 (match_operand:SI 2 "general_operand" "")
6444 (match_operand:SI 3 "" "")]
6447 rtx lab = operands[1];
6448 rtx stack = operands[2];
6449 rtx fp = operands[3];
6452 /* Trap instruction to flush all the register windows. */
6453 emit_insn (gen_flush_register_windows ());
6455 /* Load the fp value for the containing fn into %fp. This is needed
6456 because STACK refers to %fp. Note that virtual register instantiation
6457 fails if the virtual %fp isn't set from a register. */
6458 if (GET_CODE (fp) != REG)
6459 fp = force_reg (Pmode, fp);
6460 emit_move_insn (virtual_stack_vars_rtx, fp);
6462 /* Find the containing function's current nonlocal goto handler,
6463 which will do any cleanups and then jump to the label. */
6464 labreg = gen_rtx_REG (Pmode, 8);
6465 emit_move_insn (labreg, lab);
6467 /* Restore %fp from stack pointer value for containing function.
6468 The restore insn that follows will move this to %sp,
6469 and reload the appropriate value into %fp. */
6470 emit_move_insn (hard_frame_pointer_rtx, stack);
6472 emit_use (stack_pointer_rtx);
6474 /* ??? The V9-specific version was disabled in rev 1.65. */
6475 emit_jump_insn (gen_goto_handler_and_restore (labreg));
6480 ;; Special trap insn to flush register windows.
6481 (define_insn "flush_register_windows"
6482 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
6484 { return TARGET_V9 ? "flushw" : "ta\t3"; }
6485 [(set_attr "type" "flushw")])
6487 (define_insn "goto_handler_and_restore"
6488 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
6489 "GET_MODE (operands[0]) == Pmode"
6491 if (flag_delayed_branch)
6492 return "jmp\t%0\n\t restore";
6494 return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
6496 [(set (attr "type") (const_string "multi"))
6497 (set (attr "length")
6498 (if_then_else (eq_attr "delayed_branch" "true")
6502 ;; For __builtin_setjmp we need to flush register windows iff the function
6503 ;; calls alloca as well, because otherwise the register window might be
6504 ;; saved after %sp adjustment and thus setjmp would crash
6505 (define_expand "builtin_setjmp_setup"
6506 [(match_operand 0 "register_operand" "r")]
6509 emit_insn (gen_do_builtin_setjmp_setup ());
6513 (define_insn "do_builtin_setjmp_setup"
6514 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
6517 if (!cfun->calls_alloca)
6521 fputs ("\tflushw\n", asm_out_file);
6523 fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
6524 TARGET_ARCH64 ? 'x' : 'w',
6525 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
6526 fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
6527 TARGET_ARCH64 ? 'x' : 'w',
6528 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
6529 fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
6530 TARGET_ARCH64 ? 'x' : 'w',
6531 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
6534 [(set_attr "type" "multi")
6535 (set (attr "length")
6536 (cond [(eq_attr "calls_alloca" "false")
6538 (eq_attr "isa" "!v9")
6540 (eq_attr "pic" "true")
6541 (const_int 4)] (const_int 3)))])
6543 ;; Pattern for use after a setjmp to store FP and the return register
6544 ;; into the stack area.
6546 (define_expand "setjmp"
6552 mem = gen_rtx_MEM (Pmode,
6553 plus_constant (stack_pointer_rtx,
6554 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD));
6555 emit_insn (gen_rtx_SET (VOIDmode, mem, frame_pointer_rtx));
6557 mem = gen_rtx_MEM (Pmode,
6558 plus_constant (stack_pointer_rtx,
6559 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD));
6560 emit_insn (gen_rtx_SET (VOIDmode, mem, gen_rtx_REG (Pmode, 31)));
6564 ;; Special pattern for the FLUSH instruction.
6566 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
6567 ; of the define_insn otherwise missing a mode. We make "flush", aka
6568 ; gen_flush, the default one since sparc_initialize_trampoline uses
6569 ; it on SImode mem values.
6571 (define_insn "flush"
6572 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6574 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6575 [(set_attr "type" "iflush")])
6577 (define_insn "flushdi"
6578 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6580 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6581 [(set_attr "type" "iflush")])
6584 ;; Find first set instructions.
6586 ;; The scan instruction searches from the most significant bit while ffs
6587 ;; searches from the least significant bit. The bit index and treatment of
6588 ;; zero also differ. It takes at least 7 instructions to get the proper
6589 ;; result. Here is an obvious 8 instruction sequence.
6592 (define_insn "ffssi2"
6593 [(set (match_operand:SI 0 "register_operand" "=&r")
6594 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
6595 (clobber (match_scratch:SI 2 "=&r"))]
6596 "TARGET_SPARCLITE || TARGET_SPARCLET"
6598 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";
6600 [(set_attr "type" "multi")
6601 (set_attr "length" "8")])
6603 ;; ??? This should be a define expand, so that the extra instruction have
6604 ;; a chance of being optimized away.
6606 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
6607 ;; does, but no one uses that and we don't have a switch for it.
6609 ;(define_insn "ffsdi2"
6610 ; [(set (match_operand:DI 0 "register_operand" "=&r")
6611 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
6612 ; (clobber (match_scratch:DI 2 "=&r"))]
6614 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
6615 ; [(set_attr "type" "multi")
6616 ; (set_attr "length" "4")])
6620 ;; Peepholes go at the end.
6622 ;; Optimize consecutive loads or stores into ldd and std when possible.
6623 ;; The conditions in which we do this are very restricted and are
6624 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
6627 [(set (match_operand:SI 0 "memory_operand" "")
6629 (set (match_operand:SI 1 "memory_operand" "")
6632 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
6635 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
6638 [(set (match_operand:SI 0 "memory_operand" "")
6640 (set (match_operand:SI 1 "memory_operand" "")
6643 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
6646 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
6649 [(set (match_operand:SI 0 "register_operand" "")
6650 (match_operand:SI 1 "memory_operand" ""))
6651 (set (match_operand:SI 2 "register_operand" "")
6652 (match_operand:SI 3 "memory_operand" ""))]
6653 "registers_ok_for_ldd_peep (operands[0], operands[2])
6654 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6657 "operands[1] = widen_memory_access (operands[1], DImode, 0);
6658 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
6661 [(set (match_operand:SI 0 "memory_operand" "")
6662 (match_operand:SI 1 "register_operand" ""))
6663 (set (match_operand:SI 2 "memory_operand" "")
6664 (match_operand:SI 3 "register_operand" ""))]
6665 "registers_ok_for_ldd_peep (operands[1], operands[3])
6666 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6669 "operands[0] = widen_memory_access (operands[0], DImode, 0);
6670 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
6673 [(set (match_operand:SF 0 "register_operand" "")
6674 (match_operand:SF 1 "memory_operand" ""))
6675 (set (match_operand:SF 2 "register_operand" "")
6676 (match_operand:SF 3 "memory_operand" ""))]
6677 "registers_ok_for_ldd_peep (operands[0], operands[2])
6678 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6681 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
6682 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
6685 [(set (match_operand:SF 0 "memory_operand" "")
6686 (match_operand:SF 1 "register_operand" ""))
6687 (set (match_operand:SF 2 "memory_operand" "")
6688 (match_operand:SF 3 "register_operand" ""))]
6689 "registers_ok_for_ldd_peep (operands[1], operands[3])
6690 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6693 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
6694 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
6697 [(set (match_operand:SI 0 "register_operand" "")
6698 (match_operand:SI 1 "memory_operand" ""))
6699 (set (match_operand:SI 2 "register_operand" "")
6700 (match_operand:SI 3 "memory_operand" ""))]
6701 "registers_ok_for_ldd_peep (operands[2], operands[0])
6702 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6705 "operands[3] = widen_memory_access (operands[3], DImode, 0);
6706 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
6709 [(set (match_operand:SI 0 "memory_operand" "")
6710 (match_operand:SI 1 "register_operand" ""))
6711 (set (match_operand:SI 2 "memory_operand" "")
6712 (match_operand:SI 3 "register_operand" ""))]
6713 "registers_ok_for_ldd_peep (operands[3], operands[1])
6714 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6717 "operands[2] = widen_memory_access (operands[2], DImode, 0);
6718 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
6722 [(set (match_operand:SF 0 "register_operand" "")
6723 (match_operand:SF 1 "memory_operand" ""))
6724 (set (match_operand:SF 2 "register_operand" "")
6725 (match_operand:SF 3 "memory_operand" ""))]
6726 "registers_ok_for_ldd_peep (operands[2], operands[0])
6727 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6730 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
6731 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
6734 [(set (match_operand:SF 0 "memory_operand" "")
6735 (match_operand:SF 1 "register_operand" ""))
6736 (set (match_operand:SF 2 "memory_operand" "")
6737 (match_operand:SF 3 "register_operand" ""))]
6738 "registers_ok_for_ldd_peep (operands[3], operands[1])
6739 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6742 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
6743 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
6745 ;; Optimize the case of following a reg-reg move with a test
6746 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
6747 ;; This can result from a float to fix conversion.
6750 [(set (match_operand:SI 0 "register_operand" "")
6751 (match_operand:SI 1 "register_operand" ""))
6753 (compare:CC (match_operand:SI 2 "register_operand" "")
6755 "(rtx_equal_p (operands[2], operands[0])
6756 || rtx_equal_p (operands[2], operands[1]))
6757 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6758 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6759 [(parallel [(set (match_dup 0) (match_dup 1))
6761 (compare:CC (match_dup 1) (const_int 0)))])]
6765 [(set (match_operand:DI 0 "register_operand" "")
6766 (match_operand:DI 1 "register_operand" ""))
6768 (compare:CCX (match_operand:DI 2 "register_operand" "")
6771 && (rtx_equal_p (operands[2], operands[0])
6772 || rtx_equal_p (operands[2], operands[1]))
6773 && ! SPARC_FP_REG_P (REGNO (operands[0]))
6774 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6775 [(parallel [(set (match_dup 0) (match_dup 1))
6777 (compare:CCX (match_dup 1) (const_int 0)))])]
6781 ;; Prefetch instructions.
6783 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
6784 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
6785 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
6787 (define_expand "prefetch"
6788 [(match_operand 0 "address_operand" "")
6789 (match_operand 1 "const_int_operand" "")
6790 (match_operand 2 "const_int_operand" "")]
6794 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
6796 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
6800 (define_insn "prefetch_64"
6801 [(prefetch (match_operand:DI 0 "address_operand" "p")
6802 (match_operand:DI 1 "const_int_operand" "n")
6803 (match_operand:DI 2 "const_int_operand" "n"))]
6806 static const char * const prefetch_instr[2][2] = {
6808 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
6809 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
6812 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
6813 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
6816 int read_or_write = INTVAL (operands[1]);
6817 int locality = INTVAL (operands[2]);
6819 gcc_assert (read_or_write == 0 || read_or_write == 1);
6820 gcc_assert (locality >= 0 && locality < 4);
6821 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
6823 [(set_attr "type" "load")])
6825 (define_insn "prefetch_32"
6826 [(prefetch (match_operand:SI 0 "address_operand" "p")
6827 (match_operand:SI 1 "const_int_operand" "n")
6828 (match_operand:SI 2 "const_int_operand" "n"))]
6831 static const char * const prefetch_instr[2][2] = {
6833 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
6834 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
6837 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
6838 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
6841 int read_or_write = INTVAL (operands[1]);
6842 int locality = INTVAL (operands[2]);
6844 gcc_assert (read_or_write == 0 || read_or_write == 1);
6845 gcc_assert (locality >= 0 && locality < 4);
6846 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
6848 [(set_attr "type" "load")])
6851 ;; Trap instructions.
6854 [(trap_if (const_int 1) (const_int 5))]
6857 [(set_attr "type" "trap")])
6859 (define_expand "ctrapsi4"
6860 [(trap_if (match_operator 0 "noov_compare_operator"
6861 [(match_operand:SI 1 "compare_operand" "")
6862 (match_operand:SI 2 "arith_operand" "")])
6863 (match_operand 3 ""))]
6865 "operands[1] = gen_compare_reg (operands[0]);
6866 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
6868 operands[2] = const0_rtx;")
6870 (define_expand "ctrapdi4"
6871 [(trap_if (match_operator 0 "noov_compare_operator"
6872 [(match_operand:DI 1 "compare_operand" "")
6873 (match_operand:DI 2 "arith_operand" "")])
6874 (match_operand 3 ""))]
6876 "operands[1] = gen_compare_reg (operands[0]);
6877 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
6879 operands[2] = const0_rtx;")
6883 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC 100) (const_int 0)])
6884 (match_operand:SI 1 "arith_operand" "rM"))]
6888 return "t%C0\t%%icc, %1";
6892 [(set_attr "type" "trap")])
6895 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX 100) (const_int 0)])
6896 (match_operand:SI 1 "arith_operand" "rM"))]
6899 [(set_attr "type" "trap")])
6902 ;; TLS support instructions.
6904 (define_insn "tgd_hi22"
6905 [(set (match_operand:SI 0 "register_operand" "=r")
6906 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
6909 "sethi\\t%%tgd_hi22(%a1), %0")
6911 (define_insn "tgd_lo10"
6912 [(set (match_operand:SI 0 "register_operand" "=r")
6913 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
6914 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
6917 "add\\t%1, %%tgd_lo10(%a2), %0")
6919 (define_insn "tgd_add32"
6920 [(set (match_operand:SI 0 "register_operand" "=r")
6921 (plus:SI (match_operand:SI 1 "register_operand" "r")
6922 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
6923 (match_operand 3 "tgd_symbolic_operand" "")]
6925 "TARGET_TLS && TARGET_ARCH32"
6926 "add\\t%1, %2, %0, %%tgd_add(%a3)")
6928 (define_insn "tgd_add64"
6929 [(set (match_operand:DI 0 "register_operand" "=r")
6930 (plus:DI (match_operand:DI 1 "register_operand" "r")
6931 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
6932 (match_operand 3 "tgd_symbolic_operand" "")]
6934 "TARGET_TLS && TARGET_ARCH64"
6935 "add\\t%1, %2, %0, %%tgd_add(%a3)")
6937 (define_insn "tgd_call32"
6938 [(set (match_operand 0 "register_operand" "=r")
6939 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
6940 (match_operand 2 "tgd_symbolic_operand" "")]
6942 (match_operand 3 "" "")))
6943 (clobber (reg:SI 15))]
6944 "TARGET_TLS && TARGET_ARCH32"
6945 "call\t%a1, %%tgd_call(%a2)%#"
6946 [(set_attr "type" "call")])
6948 (define_insn "tgd_call64"
6949 [(set (match_operand 0 "register_operand" "=r")
6950 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
6951 (match_operand 2 "tgd_symbolic_operand" "")]
6953 (match_operand 3 "" "")))
6954 (clobber (reg:DI 15))]
6955 "TARGET_TLS && TARGET_ARCH64"
6956 "call\t%a1, %%tgd_call(%a2)%#"
6957 [(set_attr "type" "call")])
6959 (define_insn "tldm_hi22"
6960 [(set (match_operand:SI 0 "register_operand" "=r")
6961 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
6963 "sethi\\t%%tldm_hi22(%&), %0")
6965 (define_insn "tldm_lo10"
6966 [(set (match_operand:SI 0 "register_operand" "=r")
6967 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
6968 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
6970 "add\\t%1, %%tldm_lo10(%&), %0")
6972 (define_insn "tldm_add32"
6973 [(set (match_operand:SI 0 "register_operand" "=r")
6974 (plus:SI (match_operand:SI 1 "register_operand" "r")
6975 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
6977 "TARGET_TLS && TARGET_ARCH32"
6978 "add\\t%1, %2, %0, %%tldm_add(%&)")
6980 (define_insn "tldm_add64"
6981 [(set (match_operand:DI 0 "register_operand" "=r")
6982 (plus:DI (match_operand:DI 1 "register_operand" "r")
6983 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
6985 "TARGET_TLS && TARGET_ARCH64"
6986 "add\\t%1, %2, %0, %%tldm_add(%&)")
6988 (define_insn "tldm_call32"
6989 [(set (match_operand 0 "register_operand" "=r")
6990 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
6992 (match_operand 2 "" "")))
6993 (clobber (reg:SI 15))]
6994 "TARGET_TLS && TARGET_ARCH32"
6995 "call\t%a1, %%tldm_call(%&)%#"
6996 [(set_attr "type" "call")])
6998 (define_insn "tldm_call64"
6999 [(set (match_operand 0 "register_operand" "=r")
7000 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7002 (match_operand 2 "" "")))
7003 (clobber (reg:DI 15))]
7004 "TARGET_TLS && TARGET_ARCH64"
7005 "call\t%a1, %%tldm_call(%&)%#"
7006 [(set_attr "type" "call")])
7008 (define_insn "tldo_hix22"
7009 [(set (match_operand:SI 0 "register_operand" "=r")
7010 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7013 "sethi\\t%%tldo_hix22(%a1), %0")
7015 (define_insn "tldo_lox10"
7016 [(set (match_operand:SI 0 "register_operand" "=r")
7017 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7018 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7021 "xor\\t%1, %%tldo_lox10(%a2), %0")
7023 (define_insn "tldo_add32"
7024 [(set (match_operand:SI 0 "register_operand" "=r")
7025 (plus:SI (match_operand:SI 1 "register_operand" "r")
7026 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7027 (match_operand 3 "tld_symbolic_operand" "")]
7029 "TARGET_TLS && TARGET_ARCH32"
7030 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7032 (define_insn "tldo_add64"
7033 [(set (match_operand:DI 0 "register_operand" "=r")
7034 (plus:DI (match_operand:DI 1 "register_operand" "r")
7035 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7036 (match_operand 3 "tld_symbolic_operand" "")]
7038 "TARGET_TLS && TARGET_ARCH64"
7039 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7041 (define_insn "tie_hi22"
7042 [(set (match_operand:SI 0 "register_operand" "=r")
7043 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7046 "sethi\\t%%tie_hi22(%a1), %0")
7048 (define_insn "tie_lo10"
7049 [(set (match_operand:SI 0 "register_operand" "=r")
7050 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7051 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7054 "add\\t%1, %%tie_lo10(%a2), %0")
7056 (define_insn "tie_ld32"
7057 [(set (match_operand:SI 0 "register_operand" "=r")
7058 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7059 (match_operand:SI 2 "register_operand" "r")
7060 (match_operand 3 "tie_symbolic_operand" "")]
7062 "TARGET_TLS && TARGET_ARCH32"
7063 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7064 [(set_attr "type" "load")])
7066 (define_insn "tie_ld64"
7067 [(set (match_operand:DI 0 "register_operand" "=r")
7068 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7069 (match_operand:SI 2 "register_operand" "r")
7070 (match_operand 3 "tie_symbolic_operand" "")]
7072 "TARGET_TLS && TARGET_ARCH64"
7073 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7074 [(set_attr "type" "load")])
7076 (define_insn "tie_add32"
7077 [(set (match_operand:SI 0 "register_operand" "=r")
7078 (plus:SI (match_operand:SI 1 "register_operand" "r")
7079 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7080 (match_operand 3 "tie_symbolic_operand" "")]
7082 "TARGET_SUN_TLS && TARGET_ARCH32"
7083 "add\\t%1, %2, %0, %%tie_add(%a3)")
7085 (define_insn "tie_add64"
7086 [(set (match_operand:DI 0 "register_operand" "=r")
7087 (plus:DI (match_operand:DI 1 "register_operand" "r")
7088 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7089 (match_operand 3 "tie_symbolic_operand" "")]
7091 "TARGET_SUN_TLS && TARGET_ARCH64"
7092 "add\\t%1, %2, %0, %%tie_add(%a3)")
7094 (define_insn "tle_hix22_sp32"
7095 [(set (match_operand:SI 0 "register_operand" "=r")
7096 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7098 "TARGET_TLS && TARGET_ARCH32"
7099 "sethi\\t%%tle_hix22(%a1), %0")
7101 (define_insn "tle_lox10_sp32"
7102 [(set (match_operand:SI 0 "register_operand" "=r")
7103 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7104 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7106 "TARGET_TLS && TARGET_ARCH32"
7107 "xor\\t%1, %%tle_lox10(%a2), %0")
7109 (define_insn "tle_hix22_sp64"
7110 [(set (match_operand:DI 0 "register_operand" "=r")
7111 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7113 "TARGET_TLS && TARGET_ARCH64"
7114 "sethi\\t%%tle_hix22(%a1), %0")
7116 (define_insn "tle_lox10_sp64"
7117 [(set (match_operand:DI 0 "register_operand" "=r")
7118 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7119 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7121 "TARGET_TLS && TARGET_ARCH64"
7122 "xor\\t%1, %%tle_lox10(%a2), %0")
7124 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7125 (define_insn "*tldo_ldub_sp32"
7126 [(set (match_operand:QI 0 "register_operand" "=r")
7127 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7128 (match_operand 3 "tld_symbolic_operand" "")]
7130 (match_operand:SI 1 "register_operand" "r"))))]
7131 "TARGET_TLS && TARGET_ARCH32"
7132 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7133 [(set_attr "type" "load")
7134 (set_attr "us3load_type" "3cycle")])
7136 (define_insn "*tldo_ldub1_sp32"
7137 [(set (match_operand:HI 0 "register_operand" "=r")
7138 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7139 (match_operand 3 "tld_symbolic_operand" "")]
7141 (match_operand:SI 1 "register_operand" "r")))))]
7142 "TARGET_TLS && TARGET_ARCH32"
7143 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7144 [(set_attr "type" "load")
7145 (set_attr "us3load_type" "3cycle")])
7147 (define_insn "*tldo_ldub2_sp32"
7148 [(set (match_operand:SI 0 "register_operand" "=r")
7149 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7150 (match_operand 3 "tld_symbolic_operand" "")]
7152 (match_operand:SI 1 "register_operand" "r")))))]
7153 "TARGET_TLS && TARGET_ARCH32"
7154 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7155 [(set_attr "type" "load")
7156 (set_attr "us3load_type" "3cycle")])
7158 (define_insn "*tldo_ldsb1_sp32"
7159 [(set (match_operand:HI 0 "register_operand" "=r")
7160 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7161 (match_operand 3 "tld_symbolic_operand" "")]
7163 (match_operand:SI 1 "register_operand" "r")))))]
7164 "TARGET_TLS && TARGET_ARCH32"
7165 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7166 [(set_attr "type" "sload")
7167 (set_attr "us3load_type" "3cycle")])
7169 (define_insn "*tldo_ldsb2_sp32"
7170 [(set (match_operand:SI 0 "register_operand" "=r")
7171 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7172 (match_operand 3 "tld_symbolic_operand" "")]
7174 (match_operand:SI 1 "register_operand" "r")))))]
7175 "TARGET_TLS && TARGET_ARCH32"
7176 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7177 [(set_attr "type" "sload")
7178 (set_attr "us3load_type" "3cycle")])
7180 (define_insn "*tldo_ldub_sp64"
7181 [(set (match_operand:QI 0 "register_operand" "=r")
7182 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7183 (match_operand 3 "tld_symbolic_operand" "")]
7185 (match_operand:DI 1 "register_operand" "r"))))]
7186 "TARGET_TLS && TARGET_ARCH64"
7187 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7188 [(set_attr "type" "load")
7189 (set_attr "us3load_type" "3cycle")])
7191 (define_insn "*tldo_ldub1_sp64"
7192 [(set (match_operand:HI 0 "register_operand" "=r")
7193 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7194 (match_operand 3 "tld_symbolic_operand" "")]
7196 (match_operand:DI 1 "register_operand" "r")))))]
7197 "TARGET_TLS && TARGET_ARCH64"
7198 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7199 [(set_attr "type" "load")
7200 (set_attr "us3load_type" "3cycle")])
7202 (define_insn "*tldo_ldub2_sp64"
7203 [(set (match_operand:SI 0 "register_operand" "=r")
7204 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7205 (match_operand 3 "tld_symbolic_operand" "")]
7207 (match_operand:DI 1 "register_operand" "r")))))]
7208 "TARGET_TLS && TARGET_ARCH64"
7209 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7210 [(set_attr "type" "load")
7211 (set_attr "us3load_type" "3cycle")])
7213 (define_insn "*tldo_ldub3_sp64"
7214 [(set (match_operand:DI 0 "register_operand" "=r")
7215 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7216 (match_operand 3 "tld_symbolic_operand" "")]
7218 (match_operand:DI 1 "register_operand" "r")))))]
7219 "TARGET_TLS && TARGET_ARCH64"
7220 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7221 [(set_attr "type" "load")
7222 (set_attr "us3load_type" "3cycle")])
7224 (define_insn "*tldo_ldsb1_sp64"
7225 [(set (match_operand:HI 0 "register_operand" "=r")
7226 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7227 (match_operand 3 "tld_symbolic_operand" "")]
7229 (match_operand:DI 1 "register_operand" "r")))))]
7230 "TARGET_TLS && TARGET_ARCH64"
7231 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7232 [(set_attr "type" "sload")
7233 (set_attr "us3load_type" "3cycle")])
7235 (define_insn "*tldo_ldsb2_sp64"
7236 [(set (match_operand:SI 0 "register_operand" "=r")
7237 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7238 (match_operand 3 "tld_symbolic_operand" "")]
7240 (match_operand:DI 1 "register_operand" "r")))))]
7241 "TARGET_TLS && TARGET_ARCH64"
7242 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7243 [(set_attr "type" "sload")
7244 (set_attr "us3load_type" "3cycle")])
7246 (define_insn "*tldo_ldsb3_sp64"
7247 [(set (match_operand:DI 0 "register_operand" "=r")
7248 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7249 (match_operand 3 "tld_symbolic_operand" "")]
7251 (match_operand:DI 1 "register_operand" "r")))))]
7252 "TARGET_TLS && TARGET_ARCH64"
7253 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7254 [(set_attr "type" "sload")
7255 (set_attr "us3load_type" "3cycle")])
7257 (define_insn "*tldo_lduh_sp32"
7258 [(set (match_operand:HI 0 "register_operand" "=r")
7259 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7260 (match_operand 3 "tld_symbolic_operand" "")]
7262 (match_operand:SI 1 "register_operand" "r"))))]
7263 "TARGET_TLS && TARGET_ARCH32"
7264 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7265 [(set_attr "type" "load")
7266 (set_attr "us3load_type" "3cycle")])
7268 (define_insn "*tldo_lduh1_sp32"
7269 [(set (match_operand:SI 0 "register_operand" "=r")
7270 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7271 (match_operand 3 "tld_symbolic_operand" "")]
7273 (match_operand:SI 1 "register_operand" "r")))))]
7274 "TARGET_TLS && TARGET_ARCH32"
7275 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7276 [(set_attr "type" "load")
7277 (set_attr "us3load_type" "3cycle")])
7279 (define_insn "*tldo_ldsh1_sp32"
7280 [(set (match_operand:SI 0 "register_operand" "=r")
7281 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7282 (match_operand 3 "tld_symbolic_operand" "")]
7284 (match_operand:SI 1 "register_operand" "r")))))]
7285 "TARGET_TLS && TARGET_ARCH32"
7286 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7287 [(set_attr "type" "sload")
7288 (set_attr "us3load_type" "3cycle")])
7290 (define_insn "*tldo_lduh_sp64"
7291 [(set (match_operand:HI 0 "register_operand" "=r")
7292 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7293 (match_operand 3 "tld_symbolic_operand" "")]
7295 (match_operand:DI 1 "register_operand" "r"))))]
7296 "TARGET_TLS && TARGET_ARCH64"
7297 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7298 [(set_attr "type" "load")
7299 (set_attr "us3load_type" "3cycle")])
7301 (define_insn "*tldo_lduh1_sp64"
7302 [(set (match_operand:SI 0 "register_operand" "=r")
7303 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7304 (match_operand 3 "tld_symbolic_operand" "")]
7306 (match_operand:DI 1 "register_operand" "r")))))]
7307 "TARGET_TLS && TARGET_ARCH64"
7308 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7309 [(set_attr "type" "load")
7310 (set_attr "us3load_type" "3cycle")])
7312 (define_insn "*tldo_lduh2_sp64"
7313 [(set (match_operand:DI 0 "register_operand" "=r")
7314 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7315 (match_operand 3 "tld_symbolic_operand" "")]
7317 (match_operand:DI 1 "register_operand" "r")))))]
7318 "TARGET_TLS && TARGET_ARCH64"
7319 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7320 [(set_attr "type" "load")
7321 (set_attr "us3load_type" "3cycle")])
7323 (define_insn "*tldo_ldsh1_sp64"
7324 [(set (match_operand:SI 0 "register_operand" "=r")
7325 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7326 (match_operand 3 "tld_symbolic_operand" "")]
7328 (match_operand:DI 1 "register_operand" "r")))))]
7329 "TARGET_TLS && TARGET_ARCH64"
7330 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7331 [(set_attr "type" "sload")
7332 (set_attr "us3load_type" "3cycle")])
7334 (define_insn "*tldo_ldsh2_sp64"
7335 [(set (match_operand:DI 0 "register_operand" "=r")
7336 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7337 (match_operand 3 "tld_symbolic_operand" "")]
7339 (match_operand:DI 1 "register_operand" "r")))))]
7340 "TARGET_TLS && TARGET_ARCH64"
7341 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7342 [(set_attr "type" "sload")
7343 (set_attr "us3load_type" "3cycle")])
7345 (define_insn "*tldo_lduw_sp32"
7346 [(set (match_operand:SI 0 "register_operand" "=r")
7347 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7348 (match_operand 3 "tld_symbolic_operand" "")]
7350 (match_operand:SI 1 "register_operand" "r"))))]
7351 "TARGET_TLS && TARGET_ARCH32"
7352 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7353 [(set_attr "type" "load")])
7355 (define_insn "*tldo_lduw_sp64"
7356 [(set (match_operand:SI 0 "register_operand" "=r")
7357 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7358 (match_operand 3 "tld_symbolic_operand" "")]
7360 (match_operand:DI 1 "register_operand" "r"))))]
7361 "TARGET_TLS && TARGET_ARCH64"
7362 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7363 [(set_attr "type" "load")])
7365 (define_insn "*tldo_lduw1_sp64"
7366 [(set (match_operand:DI 0 "register_operand" "=r")
7367 (zero_extend:DI (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_ldsw1_sp64"
7376 [(set (match_operand:DI 0 "register_operand" "=r")
7377 (sign_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 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7383 [(set_attr "type" "sload")
7384 (set_attr "us3load_type" "3cycle")])
7386 (define_insn "*tldo_ldx_sp64"
7387 [(set (match_operand:DI 0 "register_operand" "=r")
7388 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7389 (match_operand 3 "tld_symbolic_operand" "")]
7391 (match_operand:DI 1 "register_operand" "r"))))]
7392 "TARGET_TLS && TARGET_ARCH64"
7393 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7394 [(set_attr "type" "load")])
7396 (define_insn "*tldo_stb_sp32"
7397 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7398 (match_operand 3 "tld_symbolic_operand" "")]
7400 (match_operand:SI 1 "register_operand" "r")))
7401 (match_operand:QI 0 "register_operand" "=r"))]
7402 "TARGET_TLS && TARGET_ARCH32"
7403 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7404 [(set_attr "type" "store")])
7406 (define_insn "*tldo_stb_sp64"
7407 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7408 (match_operand 3 "tld_symbolic_operand" "")]
7410 (match_operand:DI 1 "register_operand" "r")))
7411 (match_operand:QI 0 "register_operand" "=r"))]
7412 "TARGET_TLS && TARGET_ARCH64"
7413 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7414 [(set_attr "type" "store")])
7416 (define_insn "*tldo_sth_sp32"
7417 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7418 (match_operand 3 "tld_symbolic_operand" "")]
7420 (match_operand:SI 1 "register_operand" "r")))
7421 (match_operand:HI 0 "register_operand" "=r"))]
7422 "TARGET_TLS && TARGET_ARCH32"
7423 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7424 [(set_attr "type" "store")])
7426 (define_insn "*tldo_sth_sp64"
7427 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7428 (match_operand 3 "tld_symbolic_operand" "")]
7430 (match_operand:DI 1 "register_operand" "r")))
7431 (match_operand:HI 0 "register_operand" "=r"))]
7432 "TARGET_TLS && TARGET_ARCH64"
7433 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7434 [(set_attr "type" "store")])
7436 (define_insn "*tldo_stw_sp32"
7437 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7438 (match_operand 3 "tld_symbolic_operand" "")]
7440 (match_operand:SI 1 "register_operand" "r")))
7441 (match_operand:SI 0 "register_operand" "=r"))]
7442 "TARGET_TLS && TARGET_ARCH32"
7443 "st\t%0, [%1 + %2], %%tldo_add(%3)"
7444 [(set_attr "type" "store")])
7446 (define_insn "*tldo_stw_sp64"
7447 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7448 (match_operand 3 "tld_symbolic_operand" "")]
7450 (match_operand:DI 1 "register_operand" "r")))
7451 (match_operand:SI 0 "register_operand" "=r"))]
7452 "TARGET_TLS && TARGET_ARCH64"
7453 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7454 [(set_attr "type" "store")])
7456 (define_insn "*tldo_stx_sp64"
7457 [(set (mem:DI (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:DI 0 "register_operand" "=r"))]
7462 "TARGET_TLS && TARGET_ARCH64"
7463 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7464 [(set_attr "type" "store")])
7467 ;; Stack protector instructions.
7469 (define_expand "stack_protect_set"
7470 [(match_operand 0 "memory_operand" "")
7471 (match_operand 1 "memory_operand" "")]
7474 #ifdef TARGET_THREAD_SSP_OFFSET
7475 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7476 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7477 operands[1] = gen_rtx_MEM (Pmode, addr);
7480 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7482 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7486 (define_insn "stack_protect_setsi"
7487 [(set (match_operand:SI 0 "memory_operand" "=m")
7488 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7489 (set (match_scratch:SI 2 "=&r") (const_int 0))]
7491 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
7492 [(set_attr "type" "multi")
7493 (set_attr "length" "3")])
7495 (define_insn "stack_protect_setdi"
7496 [(set (match_operand:DI 0 "memory_operand" "=m")
7497 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7498 (set (match_scratch:DI 2 "=&r") (const_int 0))]
7500 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
7501 [(set_attr "type" "multi")
7502 (set_attr "length" "3")])
7504 (define_expand "stack_protect_test"
7505 [(match_operand 0 "memory_operand" "")
7506 (match_operand 1 "memory_operand" "")
7507 (match_operand 2 "" "")]
7511 #ifdef TARGET_THREAD_SSP_OFFSET
7512 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7513 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7514 operands[1] = gen_rtx_MEM (Pmode, addr);
7518 result = gen_reg_rtx (Pmode);
7519 emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
7520 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7521 emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
7525 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7526 result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
7527 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7528 emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
7533 (define_insn "stack_protect_testsi"
7535 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
7536 (match_operand:SI 1 "memory_operand" "m")]
7538 (set (match_scratch:SI 3 "=r") (const_int 0))
7539 (clobber (match_scratch:SI 2 "=&r"))]
7541 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
7542 [(set_attr "type" "multi")
7543 (set_attr "length" "4")])
7545 (define_insn "stack_protect_testdi"
7546 [(set (match_operand:DI 0 "register_operand" "=&r")
7547 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7548 (match_operand:DI 2 "memory_operand" "m")]
7550 (set (match_scratch:DI 3 "=r") (const_int 0))]
7552 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
7553 [(set_attr "type" "multi")
7554 (set_attr "length" "4")])
7557 ;; Vector instructions.
7559 (define_insn "addv2si3"
7560 [(set (match_operand:V2SI 0 "register_operand" "=e")
7561 (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7562 (match_operand:V2SI 2 "register_operand" "e")))]
7564 "fpadd32\t%1, %2, %0"
7565 [(set_attr "type" "fga")
7566 (set_attr "fptype" "double")])
7568 (define_insn "addv4hi3"
7569 [(set (match_operand:V4HI 0 "register_operand" "=e")
7570 (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7571 (match_operand:V4HI 2 "register_operand" "e")))]
7573 "fpadd16\t%1, %2, %0"
7574 [(set_attr "type" "fga")
7575 (set_attr "fptype" "double")])
7577 ;; fpadd32s is emitted by the addsi3 pattern.
7579 (define_insn "addv2hi3"
7580 [(set (match_operand:V2HI 0 "register_operand" "=f")
7581 (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7582 (match_operand:V2HI 2 "register_operand" "f")))]
7584 "fpadd16s\t%1, %2, %0"
7585 [(set_attr "type" "fga")
7586 (set_attr "fptype" "single")])
7588 (define_insn "subv2si3"
7589 [(set (match_operand:V2SI 0 "register_operand" "=e")
7590 (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7591 (match_operand:V2SI 2 "register_operand" "e")))]
7593 "fpsub32\t%1, %2, %0"
7594 [(set_attr "type" "fga")
7595 (set_attr "fptype" "double")])
7597 (define_insn "subv4hi3"
7598 [(set (match_operand:V4HI 0 "register_operand" "=e")
7599 (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7600 (match_operand:V4HI 2 "register_operand" "e")))]
7602 "fpsub16\t%1, %2, %0"
7603 [(set_attr "type" "fga")
7604 (set_attr "fptype" "double")])
7606 ;; fpsub32s is emitted by the subsi3 pattern.
7608 (define_insn "subv2hi3"
7609 [(set (match_operand:V2HI 0 "register_operand" "=f")
7610 (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7611 (match_operand:V2HI 2 "register_operand" "f")))]
7613 "fpsub16s\t%1, %2, %0"
7614 [(set_attr "type" "fga")
7615 (set_attr "fptype" "single")])
7617 ;; All other logical instructions have integer equivalents so they
7618 ;; are defined together.
7620 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
7622 (define_insn "*nand<V64:mode>_vis"
7623 [(set (match_operand:V64 0 "register_operand" "=e")
7624 (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
7625 (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
7628 [(set_attr "type" "fga")
7629 (set_attr "fptype" "double")])
7631 (define_insn "*nand<V32:mode>_vis"
7632 [(set (match_operand:V32 0 "register_operand" "=f")
7633 (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
7634 (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
7636 "fnands\t%1, %2, %0"
7637 [(set_attr "type" "fga")
7638 (set_attr "fptype" "single")])
7640 ;; Hard to generate VIS instructions. We have builtins for these.
7642 (define_insn "fpack16_vis"
7643 [(set (match_operand:V4QI 0 "register_operand" "=f")
7644 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
7648 [(set_attr "type" "fga")
7649 (set_attr "fptype" "double")])
7651 (define_insn "fpackfix_vis"
7652 [(set (match_operand:V2HI 0 "register_operand" "=f")
7653 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
7657 [(set_attr "type" "fga")
7658 (set_attr "fptype" "double")])
7660 (define_insn "fpack32_vis"
7661 [(set (match_operand:V8QI 0 "register_operand" "=e")
7662 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
7663 (match_operand:V8QI 2 "register_operand" "e")]
7666 "fpack32\t%1, %2, %0"
7667 [(set_attr "type" "fga")
7668 (set_attr "fptype" "double")])
7670 (define_insn "fexpand_vis"
7671 [(set (match_operand:V4HI 0 "register_operand" "=e")
7672 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
7676 [(set_attr "type" "fga")
7677 (set_attr "fptype" "double")])
7679 ;; It may be possible to describe this operation as (1 indexed):
7680 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
7681 ;; 1,5,10,14,19,23,28,32)
7682 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
7683 ;; because vec_merge expects all the operands to be of the same type.
7684 (define_insn "fpmerge_vis"
7685 [(set (match_operand:V8QI 0 "register_operand" "=e")
7686 (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
7687 (match_operand:V4QI 2 "register_operand" "f")]
7690 "fpmerge\t%1, %2, %0"
7691 [(set_attr "type" "fga")
7692 (set_attr "fptype" "double")])
7694 ;; Partitioned multiply instructions
7695 (define_insn "fmul8x16_vis"
7696 [(set (match_operand:V4HI 0 "register_operand" "=e")
7697 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7698 (match_operand:V4HI 2 "register_operand" "e")))]
7700 "fmul8x16\t%1, %2, %0"
7701 [(set_attr "type" "fpmul")
7702 (set_attr "fptype" "double")])
7704 ;; Only one of the following two insns can be a multiply.
7705 (define_insn "fmul8x16au_vis"
7706 [(set (match_operand:V4HI 0 "register_operand" "=e")
7707 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7708 (match_operand:V2HI 2 "register_operand" "f")))]
7710 "fmul8x16au\t%1, %2, %0"
7711 [(set_attr "type" "fpmul")
7712 (set_attr "fptype" "double")])
7714 (define_insn "fmul8x16al_vis"
7715 [(set (match_operand:V4HI 0 "register_operand" "=e")
7716 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
7717 (match_operand:V2HI 2 "register_operand" "f")]
7720 "fmul8x16al\t%1, %2, %0"
7721 [(set_attr "type" "fpmul")
7722 (set_attr "fptype" "double")])
7724 ;; Only one of the following two insns can be a multiply.
7725 (define_insn "fmul8sux16_vis"
7726 [(set (match_operand:V4HI 0 "register_operand" "=e")
7727 (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
7728 (match_operand:V4HI 2 "register_operand" "e")))]
7730 "fmul8sux16\t%1, %2, %0"
7731 [(set_attr "type" "fpmul")
7732 (set_attr "fptype" "double")])
7734 (define_insn "fmul8ulx16_vis"
7735 [(set (match_operand:V4HI 0 "register_operand" "=e")
7736 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
7737 (match_operand:V4HI 2 "register_operand" "e")]
7740 "fmul8ulx16\t%1, %2, %0"
7741 [(set_attr "type" "fpmul")
7742 (set_attr "fptype" "double")])
7744 ;; Only one of the following two insns can be a multiply.
7745 (define_insn "fmuld8sux16_vis"
7746 [(set (match_operand:V2SI 0 "register_operand" "=e")
7747 (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
7748 (match_operand:V2HI 2 "register_operand" "f")))]
7750 "fmuld8sux16\t%1, %2, %0"
7751 [(set_attr "type" "fpmul")
7752 (set_attr "fptype" "double")])
7754 (define_insn "fmuld8ulx16_vis"
7755 [(set (match_operand:V2SI 0 "register_operand" "=e")
7756 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
7757 (match_operand:V2HI 2 "register_operand" "f")]
7760 "fmuld8ulx16\t%1, %2, %0"
7761 [(set_attr "type" "fpmul")
7762 (set_attr "fptype" "double")])
7764 ;; Using faligndata only makes sense after an alignaddr since the choice of
7765 ;; bytes to take out of each operand is dependent on the results of the last
7767 (define_insn "faligndata<V64I:mode>_vis"
7768 [(set (match_operand:V64I 0 "register_operand" "=e")
7769 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
7770 (match_operand:V64I 2 "register_operand" "e")]
7773 "faligndata\t%1, %2, %0"
7774 [(set_attr "type" "fga")
7775 (set_attr "fptype" "double")])
7777 (define_insn "alignaddr<P:mode>_vis"
7778 [(set (match_operand:P 0 "register_operand" "=r")
7779 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
7780 (match_operand:P 2 "register_or_zero_operand" "rJ")]
7783 "alignaddr\t%r1, %r2, %0")
7785 (define_insn "pdist_vis"
7786 [(set (match_operand:DI 0 "register_operand" "=e")
7787 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
7788 (match_operand:V8QI 2 "register_operand" "e")
7789 (match_operand:DI 3 "register_operand" "0")]
7793 [(set_attr "type" "fga")
7794 (set_attr "fptype" "double")])