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 Free Software Foundation, Inc.
4 ;; Contributed by Michael Tiemann (tiemann@cygnus.com)
5 ;; 64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
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)
47 (UNSPEC_TLSLD_BASE 35)
59 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
60 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
61 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
62 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
63 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
65 ;; Attribute for cpu type.
66 ;; These must match the values for enum processor_type in sparc.h.
73 hypersparc,sparclite86x,
78 (const (symbol_ref "sparc_cpu_attr")))
80 ;; Attribute for the instruction set.
81 ;; At present we only need to distinguish v9/!v9, but for clarity we
82 ;; test TARGET_V8 too.
83 (define_attr "isa" "v7,v8,v9,sparclet"
85 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
86 (symbol_ref "TARGET_V8") (const_string "v8")
87 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
88 (const_string "v7"))))
94 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
102 fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,
105 multi,savew,flushw,iflush,trap"
106 (const_string "ialu"))
108 ;; True if branch/call has empty delay slot and will emit a nop in it
109 (define_attr "empty_delay_slot" "false,true"
110 (symbol_ref "empty_delay_slot (insn)"))
112 (define_attr "branch_type" "none,icc,fcc,reg"
113 (const_string "none"))
115 (define_attr "pic" "false,true"
116 (symbol_ref "flag_pic != 0"))
118 (define_attr "calls_alloca" "false,true"
119 (symbol_ref "current_function_calls_alloca != 0"))
121 (define_attr "calls_eh_return" "false,true"
122 (symbol_ref "current_function_calls_eh_return !=0 "))
124 (define_attr "leaf_function" "false,true"
125 (symbol_ref "current_function_uses_only_leaf_regs != 0"))
127 (define_attr "delayed_branch" "false,true"
128 (symbol_ref "flag_delayed_branch != 0"))
130 ;; Length (in # of insns).
131 ;; Beware that setting a length greater or equal to 3 for conditional branches
132 ;; has a side-effect (see output_cbranch and output_v9branch).
133 (define_attr "length" ""
134 (cond [(eq_attr "type" "uncond_branch,call")
135 (if_then_else (eq_attr "empty_delay_slot" "true")
138 (eq_attr "type" "sibcall")
139 (if_then_else (eq_attr "leaf_function" "true")
140 (if_then_else (eq_attr "empty_delay_slot" "true")
143 (if_then_else (eq_attr "empty_delay_slot" "true")
146 (eq_attr "branch_type" "icc")
147 (if_then_else (match_operand 0 "noov_compare64_op" "")
148 (if_then_else (lt (pc) (match_dup 1))
149 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
150 (if_then_else (eq_attr "empty_delay_slot" "true")
153 (if_then_else (eq_attr "empty_delay_slot" "true")
156 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
157 (if_then_else (eq_attr "empty_delay_slot" "true")
160 (if_then_else (eq_attr "empty_delay_slot" "true")
163 (if_then_else (eq_attr "empty_delay_slot" "true")
166 (eq_attr "branch_type" "fcc")
167 (if_then_else (match_operand 0 "fcc0_reg_operand" "")
168 (if_then_else (eq_attr "empty_delay_slot" "true")
169 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
172 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
175 (if_then_else (lt (pc) (match_dup 2))
176 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
177 (if_then_else (eq_attr "empty_delay_slot" "true")
180 (if_then_else (eq_attr "empty_delay_slot" "true")
183 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
184 (if_then_else (eq_attr "empty_delay_slot" "true")
187 (if_then_else (eq_attr "empty_delay_slot" "true")
190 (eq_attr "branch_type" "reg")
191 (if_then_else (lt (pc) (match_dup 2))
192 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
193 (if_then_else (eq_attr "empty_delay_slot" "true")
196 (if_then_else (eq_attr "empty_delay_slot" "true")
199 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
200 (if_then_else (eq_attr "empty_delay_slot" "true")
203 (if_then_else (eq_attr "empty_delay_slot" "true")
209 (define_attr "fptype" "single,double"
210 (const_string "single"))
212 ;; UltraSPARC-III integer load type.
213 (define_attr "us3load_type" "2cycle,3cycle"
214 (const_string "2cycle"))
216 (define_asm_attributes
217 [(set_attr "length" "2")
218 (set_attr "type" "multi")])
220 ;; Attributes for instruction and branch scheduling
221 (define_attr "tls_call_delay" "false,true"
222 (symbol_ref "tls_call_delay (insn)"))
224 (define_attr "in_call_delay" "false,true"
225 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
226 (const_string "false")
227 (eq_attr "type" "load,fpload,store,fpstore")
228 (if_then_else (eq_attr "length" "1")
229 (const_string "true")
230 (const_string "false"))]
231 (if_then_else (and (eq_attr "length" "1")
232 (eq_attr "tls_call_delay" "true"))
233 (const_string "true")
234 (const_string "false"))))
236 (define_attr "eligible_for_sibcall_delay" "false,true"
237 (symbol_ref "eligible_for_sibcall_delay (insn)"))
239 (define_attr "eligible_for_return_delay" "false,true"
240 (symbol_ref "eligible_for_return_delay (insn)"))
242 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
243 ;; branches. This would allow us to remove the nop always inserted before
244 ;; a floating point branch.
246 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
247 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
248 ;; This is because doing so will add several pipeline stalls to the path
249 ;; that the load/store did not come from. Unfortunately, there is no way
250 ;; to prevent fill_eager_delay_slots from using load/store without completely
251 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
252 ;; because it prevents us from moving back the final store of inner loops.
254 (define_attr "in_branch_delay" "false,true"
255 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
256 (eq_attr "length" "1"))
257 (const_string "true")
258 (const_string "false")))
260 (define_attr "in_uncond_branch_delay" "false,true"
261 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
262 (eq_attr "length" "1"))
263 (const_string "true")
264 (const_string "false")))
266 (define_attr "in_annul_branch_delay" "false,true"
267 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
268 (eq_attr "length" "1"))
269 (const_string "true")
270 (const_string "false")))
272 (define_delay (eq_attr "type" "call")
273 [(eq_attr "in_call_delay" "true") (nil) (nil)])
275 (define_delay (eq_attr "type" "sibcall")
276 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
278 (define_delay (eq_attr "type" "branch")
279 [(eq_attr "in_branch_delay" "true")
280 (nil) (eq_attr "in_annul_branch_delay" "true")])
282 (define_delay (eq_attr "type" "uncond_branch")
283 [(eq_attr "in_uncond_branch_delay" "true")
286 (define_delay (eq_attr "type" "return")
287 [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
289 ;; Include SPARC DFA schedulers
291 (include "cypress.md")
292 (include "supersparc.md")
293 (include "hypersparc.md")
294 (include "sparclet.md")
295 (include "ultra1_2.md")
296 (include "ultra3.md")
299 ;; Compare instructions.
300 ;; This controls RTL generation and register allocation.
302 ;; We generate RTL for comparisons and branches by having the cmpxx
303 ;; patterns store away the operands. Then, the scc and bcc patterns
304 ;; emit RTL for both the compare and the branch.
306 ;; We do this because we want to generate different code for an sne and
307 ;; seq insn. In those cases, if the second operand of the compare is not
308 ;; const0_rtx, we want to compute the xor of the two operands and test
311 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
312 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
313 ;; insns that actually require more than one machine instruction.
315 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
317 (define_expand "cmpsi"
319 (compare:CC (match_operand:SI 0 "compare_operand" "")
320 (match_operand:SI 1 "arith_operand" "")))]
323 if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
324 operands[0] = force_reg (SImode, operands[0]);
326 sparc_compare_op0 = operands[0];
327 sparc_compare_op1 = operands[1];
331 (define_expand "cmpdi"
333 (compare:CCX (match_operand:DI 0 "compare_operand" "")
334 (match_operand:DI 1 "arith_double_operand" "")))]
337 if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
338 operands[0] = force_reg (DImode, operands[0]);
340 sparc_compare_op0 = operands[0];
341 sparc_compare_op1 = operands[1];
345 (define_expand "cmpsf"
346 ;; The 96 here isn't ever used by anyone.
348 (compare:CCFP (match_operand:SF 0 "register_operand" "")
349 (match_operand:SF 1 "register_operand" "")))]
352 sparc_compare_op0 = operands[0];
353 sparc_compare_op1 = operands[1];
357 (define_expand "cmpdf"
358 ;; The 96 here isn't ever used by anyone.
360 (compare:CCFP (match_operand:DF 0 "register_operand" "")
361 (match_operand:DF 1 "register_operand" "")))]
364 sparc_compare_op0 = operands[0];
365 sparc_compare_op1 = operands[1];
369 (define_expand "cmptf"
370 ;; The 96 here isn't ever used by anyone.
372 (compare:CCFP (match_operand:TF 0 "register_operand" "")
373 (match_operand:TF 1 "register_operand" "")))]
376 sparc_compare_op0 = operands[0];
377 sparc_compare_op1 = operands[1];
381 ;; Now the compare DEFINE_INSNs.
383 (define_insn "*cmpsi_insn"
385 (compare:CC (match_operand:SI 0 "register_operand" "r")
386 (match_operand:SI 1 "arith_operand" "rI")))]
389 [(set_attr "type" "compare")])
391 (define_insn "*cmpdi_sp64"
393 (compare:CCX (match_operand:DI 0 "register_operand" "r")
394 (match_operand:DI 1 "arith_double_operand" "rHI")))]
397 [(set_attr "type" "compare")])
399 (define_insn "*cmpsf_fpe"
400 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
401 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
402 (match_operand:SF 2 "register_operand" "f")))]
406 return "fcmpes\t%0, %1, %2";
407 return "fcmpes\t%1, %2";
409 [(set_attr "type" "fpcmp")])
411 (define_insn "*cmpdf_fpe"
412 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
413 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
414 (match_operand:DF 2 "register_operand" "e")))]
418 return "fcmped\t%0, %1, %2";
419 return "fcmped\t%1, %2";
421 [(set_attr "type" "fpcmp")
422 (set_attr "fptype" "double")])
424 (define_insn "*cmptf_fpe"
425 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
426 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
427 (match_operand:TF 2 "register_operand" "e")))]
428 "TARGET_FPU && TARGET_HARD_QUAD"
431 return "fcmpeq\t%0, %1, %2";
432 return "fcmpeq\t%1, %2";
434 [(set_attr "type" "fpcmp")])
436 (define_insn "*cmpsf_fp"
437 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
438 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
439 (match_operand:SF 2 "register_operand" "f")))]
443 return "fcmps\t%0, %1, %2";
444 return "fcmps\t%1, %2";
446 [(set_attr "type" "fpcmp")])
448 (define_insn "*cmpdf_fp"
449 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
450 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
451 (match_operand:DF 2 "register_operand" "e")))]
455 return "fcmpd\t%0, %1, %2";
456 return "fcmpd\t%1, %2";
458 [(set_attr "type" "fpcmp")
459 (set_attr "fptype" "double")])
461 (define_insn "*cmptf_fp"
462 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
463 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
464 (match_operand:TF 2 "register_operand" "e")))]
465 "TARGET_FPU && TARGET_HARD_QUAD"
468 return "fcmpq\t%0, %1, %2";
469 return "fcmpq\t%1, %2";
471 [(set_attr "type" "fpcmp")])
473 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
474 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
475 ;; the same code as v8 (the addx/subx method has more applications). The
476 ;; exception to this is "reg != 0" which can be done in one instruction on v9
477 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
480 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
481 ;; generate addcc/subcc instructions.
483 (define_expand "seqsi_special"
485 (xor:SI (match_operand:SI 1 "register_operand" "")
486 (match_operand:SI 2 "register_operand" "")))
487 (parallel [(set (match_operand:SI 0 "register_operand" "")
488 (eq:SI (match_dup 3) (const_int 0)))
489 (clobber (reg:CC 100))])]
491 { operands[3] = gen_reg_rtx (SImode); })
493 (define_expand "seqdi_special"
495 (xor:DI (match_operand:DI 1 "register_operand" "")
496 (match_operand:DI 2 "register_operand" "")))
497 (set (match_operand:DI 0 "register_operand" "")
498 (eq:DI (match_dup 3) (const_int 0)))]
500 { operands[3] = gen_reg_rtx (DImode); })
502 (define_expand "snesi_special"
504 (xor:SI (match_operand:SI 1 "register_operand" "")
505 (match_operand:SI 2 "register_operand" "")))
506 (parallel [(set (match_operand:SI 0 "register_operand" "")
507 (ne:SI (match_dup 3) (const_int 0)))
508 (clobber (reg:CC 100))])]
510 { operands[3] = gen_reg_rtx (SImode); })
512 (define_expand "snedi_special"
514 (xor:DI (match_operand:DI 1 "register_operand" "")
515 (match_operand:DI 2 "register_operand" "")))
516 (set (match_operand:DI 0 "register_operand" "")
517 (ne:DI (match_dup 3) (const_int 0)))]
519 { operands[3] = gen_reg_rtx (DImode); })
521 (define_expand "seqdi_special_trunc"
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 (eq:SI (match_dup 3) (const_int 0)))]
528 { operands[3] = gen_reg_rtx (DImode); })
530 (define_expand "snedi_special_trunc"
532 (xor:DI (match_operand:DI 1 "register_operand" "")
533 (match_operand:DI 2 "register_operand" "")))
534 (set (match_operand:SI 0 "register_operand" "")
535 (ne:SI (match_dup 3) (const_int 0)))]
537 { operands[3] = gen_reg_rtx (DImode); })
539 (define_expand "seqsi_special_extend"
541 (xor:SI (match_operand:SI 1 "register_operand" "")
542 (match_operand:SI 2 "register_operand" "")))
543 (parallel [(set (match_operand:DI 0 "register_operand" "")
544 (eq:DI (match_dup 3) (const_int 0)))
545 (clobber (reg:CC 100))])]
547 { operands[3] = gen_reg_rtx (SImode); })
549 (define_expand "snesi_special_extend"
551 (xor:SI (match_operand:SI 1 "register_operand" "")
552 (match_operand:SI 2 "register_operand" "")))
553 (parallel [(set (match_operand:DI 0 "register_operand" "")
554 (ne:DI (match_dup 3) (const_int 0)))
555 (clobber (reg:CC 100))])]
557 { operands[3] = gen_reg_rtx (SImode); })
559 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
560 ;; However, the code handles both SImode and DImode.
562 [(set (match_operand:SI 0 "intreg_operand" "")
563 (eq:SI (match_dup 1) (const_int 0)))]
566 if (GET_MODE (sparc_compare_op0) == SImode)
570 if (GET_MODE (operands[0]) == SImode)
571 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
573 else if (! TARGET_ARCH64)
576 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
581 else if (GET_MODE (sparc_compare_op0) == DImode)
587 else if (GET_MODE (operands[0]) == SImode)
588 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
591 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
596 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
598 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
599 emit_jump_insn (gen_sne (operands[0]));
604 if (gen_v9_scc (EQ, operands))
611 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
612 ;; However, the code handles both SImode and DImode.
614 [(set (match_operand:SI 0 "intreg_operand" "")
615 (ne:SI (match_dup 1) (const_int 0)))]
618 if (GET_MODE (sparc_compare_op0) == SImode)
622 if (GET_MODE (operands[0]) == SImode)
623 pat = gen_snesi_special (operands[0], sparc_compare_op0,
625 else if (! TARGET_ARCH64)
628 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
633 else if (GET_MODE (sparc_compare_op0) == DImode)
639 else if (GET_MODE (operands[0]) == SImode)
640 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
643 pat = gen_snedi_special (operands[0], sparc_compare_op0,
648 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
650 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
651 emit_jump_insn (gen_sne (operands[0]));
656 if (gen_v9_scc (NE, operands))
664 [(set (match_operand:SI 0 "intreg_operand" "")
665 (gt:SI (match_dup 1) (const_int 0)))]
668 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
670 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
671 emit_jump_insn (gen_sne (operands[0]));
676 if (gen_v9_scc (GT, operands))
684 [(set (match_operand:SI 0 "intreg_operand" "")
685 (lt:SI (match_dup 1) (const_int 0)))]
688 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
690 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
691 emit_jump_insn (gen_sne (operands[0]));
696 if (gen_v9_scc (LT, operands))
704 [(set (match_operand:SI 0 "intreg_operand" "")
705 (ge:SI (match_dup 1) (const_int 0)))]
708 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
710 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
711 emit_jump_insn (gen_sne (operands[0]));
716 if (gen_v9_scc (GE, operands))
724 [(set (match_operand:SI 0 "intreg_operand" "")
725 (le:SI (match_dup 1) (const_int 0)))]
728 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
730 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
731 emit_jump_insn (gen_sne (operands[0]));
736 if (gen_v9_scc (LE, operands))
743 (define_expand "sgtu"
744 [(set (match_operand:SI 0 "intreg_operand" "")
745 (gtu:SI (match_dup 1) (const_int 0)))]
752 /* We can do ltu easily, so if both operands are registers, swap them and
754 if ((GET_CODE (sparc_compare_op0) == REG
755 || GET_CODE (sparc_compare_op0) == SUBREG)
756 && (GET_CODE (sparc_compare_op1) == REG
757 || GET_CODE (sparc_compare_op1) == SUBREG))
759 tem = sparc_compare_op0;
760 sparc_compare_op0 = sparc_compare_op1;
761 sparc_compare_op1 = tem;
762 pat = gen_sltu (operands[0]);
771 if (gen_v9_scc (GTU, operands))
777 (define_expand "sltu"
778 [(set (match_operand:SI 0 "intreg_operand" "")
779 (ltu:SI (match_dup 1) (const_int 0)))]
784 if (gen_v9_scc (LTU, operands))
787 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
790 (define_expand "sgeu"
791 [(set (match_operand:SI 0 "intreg_operand" "")
792 (geu:SI (match_dup 1) (const_int 0)))]
797 if (gen_v9_scc (GEU, operands))
800 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
803 (define_expand "sleu"
804 [(set (match_operand:SI 0 "intreg_operand" "")
805 (leu:SI (match_dup 1) (const_int 0)))]
812 /* We can do geu easily, so if both operands are registers, swap them and
814 if ((GET_CODE (sparc_compare_op0) == REG
815 || GET_CODE (sparc_compare_op0) == SUBREG)
816 && (GET_CODE (sparc_compare_op1) == REG
817 || GET_CODE (sparc_compare_op1) == SUBREG))
819 tem = sparc_compare_op0;
820 sparc_compare_op0 = sparc_compare_op1;
821 sparc_compare_op1 = tem;
822 pat = gen_sgeu (operands[0]);
831 if (gen_v9_scc (LEU, operands))
837 ;; Now the DEFINE_INSNs for the scc cases.
839 ;; The SEQ and SNE patterns are special because they can be done
840 ;; without any branching and do not involve a COMPARE. We want
841 ;; them to always use the splitz below so the results can be
844 (define_insn_and_split "*snesi_zero"
845 [(set (match_operand:SI 0 "register_operand" "=r")
846 (ne:SI (match_operand:SI 1 "register_operand" "r")
848 (clobber (reg:CC 100))]
852 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
854 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
856 [(set_attr "length" "2")])
858 (define_insn_and_split "*neg_snesi_zero"
859 [(set (match_operand:SI 0 "register_operand" "=r")
860 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
862 (clobber (reg:CC 100))]
866 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
868 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
870 [(set_attr "length" "2")])
872 (define_insn_and_split "*snesi_zero_extend"
873 [(set (match_operand:DI 0 "register_operand" "=r")
874 (ne:DI (match_operand:SI 1 "register_operand" "r")
876 (clobber (reg:CC 100))]
880 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
883 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
885 (ltu:SI (reg:CC_NOOV 100)
888 [(set_attr "length" "2")])
890 (define_insn_and_split "*snedi_zero"
891 [(set (match_operand:DI 0 "register_operand" "=&r")
892 (ne:DI (match_operand:DI 1 "register_operand" "r")
896 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
897 [(set (match_dup 0) (const_int 0))
898 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
903 [(set_attr "length" "2")])
905 (define_insn_and_split "*neg_snedi_zero"
906 [(set (match_operand:DI 0 "register_operand" "=&r")
907 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
911 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
912 [(set (match_dup 0) (const_int 0))
913 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
918 [(set_attr "length" "2")])
920 (define_insn_and_split "*snedi_zero_trunc"
921 [(set (match_operand:SI 0 "register_operand" "=&r")
922 (ne:SI (match_operand:DI 1 "register_operand" "r")
926 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
927 [(set (match_dup 0) (const_int 0))
928 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
933 [(set_attr "length" "2")])
935 (define_insn_and_split "*seqsi_zero"
936 [(set (match_operand:SI 0 "register_operand" "=r")
937 (eq:SI (match_operand:SI 1 "register_operand" "r")
939 (clobber (reg:CC 100))]
943 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
945 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
947 [(set_attr "length" "2")])
949 (define_insn_and_split "*neg_seqsi_zero"
950 [(set (match_operand:SI 0 "register_operand" "=r")
951 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
953 (clobber (reg:CC 100))]
957 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
959 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
961 [(set_attr "length" "2")])
963 (define_insn_and_split "*seqsi_zero_extend"
964 [(set (match_operand:DI 0 "register_operand" "=r")
965 (eq:DI (match_operand:SI 1 "register_operand" "r")
967 (clobber (reg:CC 100))]
971 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
974 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
976 (ltu:SI (reg:CC_NOOV 100)
979 [(set_attr "length" "2")])
981 (define_insn_and_split "*seqdi_zero"
982 [(set (match_operand:DI 0 "register_operand" "=&r")
983 (eq:DI (match_operand:DI 1 "register_operand" "r")
987 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
988 [(set (match_dup 0) (const_int 0))
989 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
994 [(set_attr "length" "2")])
996 (define_insn_and_split "*neg_seqdi_zero"
997 [(set (match_operand:DI 0 "register_operand" "=&r")
998 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1002 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1003 [(set (match_dup 0) (const_int 0))
1004 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1009 [(set_attr "length" "2")])
1011 (define_insn_and_split "*seqdi_zero_trunc"
1012 [(set (match_operand:SI 0 "register_operand" "=&r")
1013 (eq:SI (match_operand:DI 1 "register_operand" "r")
1017 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1018 [(set (match_dup 0) (const_int 0))
1019 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1024 [(set_attr "length" "2")])
1026 ;; We can also do (x + (i == 0)) and related, so put them in.
1027 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1030 (define_insn_and_split "*x_plus_i_ne_0"
1031 [(set (match_operand:SI 0 "register_operand" "=r")
1032 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1034 (match_operand:SI 2 "register_operand" "r")))
1035 (clobber (reg:CC 100))]
1039 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1041 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1044 [(set_attr "length" "2")])
1046 (define_insn_and_split "*x_minus_i_ne_0"
1047 [(set (match_operand:SI 0 "register_operand" "=r")
1048 (minus:SI (match_operand:SI 2 "register_operand" "r")
1049 (ne:SI (match_operand:SI 1 "register_operand" "r")
1051 (clobber (reg:CC 100))]
1055 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1057 (set (match_dup 0) (minus:SI (match_dup 2)
1058 (ltu:SI (reg:CC 100) (const_int 0))))]
1060 [(set_attr "length" "2")])
1062 (define_insn_and_split "*x_plus_i_eq_0"
1063 [(set (match_operand:SI 0 "register_operand" "=r")
1064 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1066 (match_operand:SI 2 "register_operand" "r")))
1067 (clobber (reg:CC 100))]
1071 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1073 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1076 [(set_attr "length" "2")])
1078 (define_insn_and_split "*x_minus_i_eq_0"
1079 [(set (match_operand:SI 0 "register_operand" "=r")
1080 (minus:SI (match_operand:SI 2 "register_operand" "r")
1081 (eq:SI (match_operand:SI 1 "register_operand" "r")
1083 (clobber (reg:CC 100))]
1087 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1089 (set (match_dup 0) (minus:SI (match_dup 2)
1090 (geu:SI (reg:CC 100) (const_int 0))))]
1092 [(set_attr "length" "2")])
1094 ;; We can also do GEU and LTU directly, but these operate after a compare.
1095 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1098 (define_insn "*sltu_insn"
1099 [(set (match_operand:SI 0 "register_operand" "=r")
1100 (ltu:SI (reg:CC 100) (const_int 0)))]
1103 [(set_attr "type" "ialuX")])
1105 (define_insn "*neg_sltu_insn"
1106 [(set (match_operand:SI 0 "register_operand" "=r")
1107 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1110 [(set_attr "type" "ialuX")])
1112 ;; ??? Combine should canonicalize these next two to the same pattern.
1113 (define_insn "*neg_sltu_minus_x"
1114 [(set (match_operand:SI 0 "register_operand" "=r")
1115 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1116 (match_operand:SI 1 "arith_operand" "rI")))]
1118 "subx\t%%g0, %1, %0"
1119 [(set_attr "type" "ialuX")])
1121 (define_insn "*neg_sltu_plus_x"
1122 [(set (match_operand:SI 0 "register_operand" "=r")
1123 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1124 (match_operand:SI 1 "arith_operand" "rI"))))]
1126 "subx\t%%g0, %1, %0"
1127 [(set_attr "type" "ialuX")])
1129 (define_insn "*sgeu_insn"
1130 [(set (match_operand:SI 0 "register_operand" "=r")
1131 (geu:SI (reg:CC 100) (const_int 0)))]
1133 "subx\t%%g0, -1, %0"
1134 [(set_attr "type" "ialuX")])
1136 (define_insn "*neg_sgeu_insn"
1137 [(set (match_operand:SI 0 "register_operand" "=r")
1138 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1140 "addx\t%%g0, -1, %0"
1141 [(set_attr "type" "ialuX")])
1143 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1144 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1147 (define_insn "*sltu_plus_x"
1148 [(set (match_operand:SI 0 "register_operand" "=r")
1149 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1150 (match_operand:SI 1 "arith_operand" "rI")))]
1152 "addx\t%%g0, %1, %0"
1153 [(set_attr "type" "ialuX")])
1155 (define_insn "*sltu_plus_x_plus_y"
1156 [(set (match_operand:SI 0 "register_operand" "=r")
1157 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1158 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1159 (match_operand:SI 2 "arith_operand" "rI"))))]
1162 [(set_attr "type" "ialuX")])
1164 (define_insn "*x_minus_sltu"
1165 [(set (match_operand:SI 0 "register_operand" "=r")
1166 (minus:SI (match_operand:SI 1 "register_operand" "r")
1167 (ltu:SI (reg:CC 100) (const_int 0))))]
1170 [(set_attr "type" "ialuX")])
1172 ;; ??? Combine should canonicalize these next two to the same pattern.
1173 (define_insn "*x_minus_y_minus_sltu"
1174 [(set (match_operand:SI 0 "register_operand" "=r")
1175 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1176 (match_operand:SI 2 "arith_operand" "rI"))
1177 (ltu:SI (reg:CC 100) (const_int 0))))]
1180 [(set_attr "type" "ialuX")])
1182 (define_insn "*x_minus_sltu_plus_y"
1183 [(set (match_operand:SI 0 "register_operand" "=r")
1184 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1185 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1186 (match_operand:SI 2 "arith_operand" "rI"))))]
1189 [(set_attr "type" "ialuX")])
1191 (define_insn "*sgeu_plus_x"
1192 [(set (match_operand:SI 0 "register_operand" "=r")
1193 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1194 (match_operand:SI 1 "register_operand" "r")))]
1197 [(set_attr "type" "ialuX")])
1199 (define_insn "*x_minus_sgeu"
1200 [(set (match_operand:SI 0 "register_operand" "=r")
1201 (minus:SI (match_operand:SI 1 "register_operand" "r")
1202 (geu:SI (reg:CC 100) (const_int 0))))]
1205 [(set_attr "type" "ialuX")])
1208 [(set (match_operand:SI 0 "register_operand" "")
1209 (match_operator:SI 2 "noov_compare_op"
1210 [(match_operand 1 "icc_or_fcc_reg_operand" "")
1212 ;; 32 bit LTU/GEU are better implemented using addx/subx
1213 "TARGET_V9 && REGNO (operands[1]) == SPARC_ICC_REG
1214 && (GET_MODE (operands[1]) == CCXmode
1215 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1216 [(set (match_dup 0) (const_int 0))
1218 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1224 ;; These control RTL generation for conditional jump insns
1226 ;; The quad-word fp compare library routines all return nonzero to indicate
1227 ;; true, which is different from the equivalent libgcc routines, so we must
1228 ;; handle them specially here.
1230 (define_expand "beq"
1232 (if_then_else (eq (match_dup 1) (const_int 0))
1233 (label_ref (match_operand 0 "" ""))
1237 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1238 && GET_CODE (sparc_compare_op0) == REG
1239 && GET_MODE (sparc_compare_op0) == DImode)
1241 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1244 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1246 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1247 emit_jump_insn (gen_bne (operands[0]));
1250 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1253 (define_expand "bne"
1255 (if_then_else (ne (match_dup 1) (const_int 0))
1256 (label_ref (match_operand 0 "" ""))
1260 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1261 && GET_CODE (sparc_compare_op0) == REG
1262 && GET_MODE (sparc_compare_op0) == DImode)
1264 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1267 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1269 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1270 emit_jump_insn (gen_bne (operands[0]));
1273 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1276 (define_expand "bgt"
1278 (if_then_else (gt (match_dup 1) (const_int 0))
1279 (label_ref (match_operand 0 "" ""))
1283 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1284 && GET_CODE (sparc_compare_op0) == REG
1285 && GET_MODE (sparc_compare_op0) == DImode)
1287 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1290 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1292 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1293 emit_jump_insn (gen_bne (operands[0]));
1296 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1299 (define_expand "bgtu"
1301 (if_then_else (gtu (match_dup 1) (const_int 0))
1302 (label_ref (match_operand 0 "" ""))
1306 operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1309 (define_expand "blt"
1311 (if_then_else (lt (match_dup 1) (const_int 0))
1312 (label_ref (match_operand 0 "" ""))
1316 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1317 && GET_CODE (sparc_compare_op0) == REG
1318 && GET_MODE (sparc_compare_op0) == DImode)
1320 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1323 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1325 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1326 emit_jump_insn (gen_bne (operands[0]));
1329 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1332 (define_expand "bltu"
1334 (if_then_else (ltu (match_dup 1) (const_int 0))
1335 (label_ref (match_operand 0 "" ""))
1339 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1342 (define_expand "bge"
1344 (if_then_else (ge (match_dup 1) (const_int 0))
1345 (label_ref (match_operand 0 "" ""))
1349 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1350 && GET_CODE (sparc_compare_op0) == REG
1351 && GET_MODE (sparc_compare_op0) == DImode)
1353 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1356 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1358 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1359 emit_jump_insn (gen_bne (operands[0]));
1362 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1365 (define_expand "bgeu"
1367 (if_then_else (geu (match_dup 1) (const_int 0))
1368 (label_ref (match_operand 0 "" ""))
1372 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1375 (define_expand "ble"
1377 (if_then_else (le (match_dup 1) (const_int 0))
1378 (label_ref (match_operand 0 "" ""))
1382 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1383 && GET_CODE (sparc_compare_op0) == REG
1384 && GET_MODE (sparc_compare_op0) == DImode)
1386 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1389 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1391 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1392 emit_jump_insn (gen_bne (operands[0]));
1395 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1398 (define_expand "bleu"
1400 (if_then_else (leu (match_dup 1) (const_int 0))
1401 (label_ref (match_operand 0 "" ""))
1405 operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1408 (define_expand "bunordered"
1410 (if_then_else (unordered (match_dup 1) (const_int 0))
1411 (label_ref (match_operand 0 "" ""))
1415 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1417 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1419 emit_jump_insn (gen_beq (operands[0]));
1422 operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
1426 (define_expand "bordered"
1428 (if_then_else (ordered (match_dup 1) (const_int 0))
1429 (label_ref (match_operand 0 "" ""))
1433 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1435 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1436 emit_jump_insn (gen_bne (operands[0]));
1439 operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
1443 (define_expand "bungt"
1445 (if_then_else (ungt (match_dup 1) (const_int 0))
1446 (label_ref (match_operand 0 "" ""))
1450 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1452 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1453 emit_jump_insn (gen_bgt (operands[0]));
1456 operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
1459 (define_expand "bunlt"
1461 (if_then_else (unlt (match_dup 1) (const_int 0))
1462 (label_ref (match_operand 0 "" ""))
1466 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1468 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1469 emit_jump_insn (gen_bne (operands[0]));
1472 operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
1475 (define_expand "buneq"
1477 (if_then_else (uneq (match_dup 1) (const_int 0))
1478 (label_ref (match_operand 0 "" ""))
1482 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1484 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1485 emit_jump_insn (gen_beq (operands[0]));
1488 operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
1491 (define_expand "bunge"
1493 (if_then_else (unge (match_dup 1) (const_int 0))
1494 (label_ref (match_operand 0 "" ""))
1498 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1500 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1501 emit_jump_insn (gen_bne (operands[0]));
1504 operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
1507 (define_expand "bunle"
1509 (if_then_else (unle (match_dup 1) (const_int 0))
1510 (label_ref (match_operand 0 "" ""))
1514 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1516 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1517 emit_jump_insn (gen_bne (operands[0]));
1520 operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
1523 (define_expand "bltgt"
1525 (if_then_else (ltgt (match_dup 1) (const_int 0))
1526 (label_ref (match_operand 0 "" ""))
1530 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1532 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1533 emit_jump_insn (gen_bne (operands[0]));
1536 operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1);
1539 ;; Now match both normal and inverted jump.
1541 ;; XXX fpcmp nop braindamage
1542 (define_insn "*normal_branch"
1544 (if_then_else (match_operator 0 "noov_compare_op"
1545 [(reg 100) (const_int 0)])
1546 (label_ref (match_operand 1 "" ""))
1550 return output_cbranch (operands[0], operands[1], 1, 0,
1551 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1554 [(set_attr "type" "branch")
1555 (set_attr "branch_type" "icc")])
1557 ;; XXX fpcmp nop braindamage
1558 (define_insn "*inverted_branch"
1560 (if_then_else (match_operator 0 "noov_compare_op"
1561 [(reg 100) (const_int 0)])
1563 (label_ref (match_operand 1 "" ""))))]
1566 return output_cbranch (operands[0], operands[1], 1, 1,
1567 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1570 [(set_attr "type" "branch")
1571 (set_attr "branch_type" "icc")])
1573 ;; XXX fpcmp nop braindamage
1574 (define_insn "*normal_fp_branch"
1576 (if_then_else (match_operator 1 "comparison_operator"
1577 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1579 (label_ref (match_operand 2 "" ""))
1583 return output_cbranch (operands[1], operands[2], 2, 0,
1584 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1587 [(set_attr "type" "branch")
1588 (set_attr "branch_type" "fcc")])
1590 ;; XXX fpcmp nop braindamage
1591 (define_insn "*inverted_fp_branch"
1593 (if_then_else (match_operator 1 "comparison_operator"
1594 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1597 (label_ref (match_operand 2 "" ""))))]
1600 return output_cbranch (operands[1], operands[2], 2, 1,
1601 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1604 [(set_attr "type" "branch")
1605 (set_attr "branch_type" "fcc")])
1607 ;; XXX fpcmp nop braindamage
1608 (define_insn "*normal_fpe_branch"
1610 (if_then_else (match_operator 1 "comparison_operator"
1611 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1613 (label_ref (match_operand 2 "" ""))
1617 return output_cbranch (operands[1], operands[2], 2, 0,
1618 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1621 [(set_attr "type" "branch")
1622 (set_attr "branch_type" "fcc")])
1624 ;; XXX fpcmp nop braindamage
1625 (define_insn "*inverted_fpe_branch"
1627 (if_then_else (match_operator 1 "comparison_operator"
1628 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1631 (label_ref (match_operand 2 "" ""))))]
1634 return output_cbranch (operands[1], operands[2], 2, 1,
1635 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1638 [(set_attr "type" "branch")
1639 (set_attr "branch_type" "fcc")])
1641 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1642 ;; in the architecture.
1644 ;; There are no 32 bit brreg insns.
1647 (define_insn "*normal_int_branch_sp64"
1649 (if_then_else (match_operator 0 "v9_regcmp_op"
1650 [(match_operand:DI 1 "register_operand" "r")
1652 (label_ref (match_operand 2 "" ""))
1656 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1657 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1660 [(set_attr "type" "branch")
1661 (set_attr "branch_type" "reg")])
1664 (define_insn "*inverted_int_branch_sp64"
1666 (if_then_else (match_operator 0 "v9_regcmp_op"
1667 [(match_operand:DI 1 "register_operand" "r")
1670 (label_ref (match_operand 2 "" ""))))]
1673 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1674 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1677 [(set_attr "type" "branch")
1678 (set_attr "branch_type" "reg")])
1680 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1681 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1682 ;; that adds the PC value at the call point to operand 0.
1684 (define_insn "load_pcrel_sym"
1685 [(set (match_operand 0 "register_operand" "=r")
1686 (unspec [(match_operand 1 "symbolic_operand" "")
1687 (match_operand 2 "call_operand_address" "")] UNSPEC_LOAD_PCREL_SYM))
1688 (clobber (reg:SI 15))]
1691 if (flag_delayed_branch)
1692 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1694 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1696 [(set (attr "type") (const_string "multi"))
1697 (set (attr "length")
1698 (if_then_else (eq_attr "delayed_branch" "true")
1702 ;; Move instructions
1704 (define_expand "movqi"
1705 [(set (match_operand:QI 0 "general_operand" "")
1706 (match_operand:QI 1 "general_operand" ""))]
1709 /* Working with CONST_INTs is easier, so convert
1710 a double if needed. */
1711 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1713 operands[1] = GEN_INT (trunc_int_for_mode
1714 (CONST_DOUBLE_LOW (operands[1]), QImode));
1717 /* Handle sets of MEM first. */
1718 if (GET_CODE (operands[0]) == MEM)
1720 if (reg_or_0_operand (operands[1], QImode))
1723 if (! reload_in_progress)
1725 operands[0] = validize_mem (operands[0]);
1726 operands[1] = force_reg (QImode, operands[1]);
1730 /* Fixup TLS cases. */
1731 if (tls_symbolic_operand (operands [1]))
1732 operands[1] = legitimize_tls_address (operands[1]);
1734 /* Fixup PIC cases. */
1737 if (CONSTANT_P (operands[1])
1738 && pic_address_needs_scratch (operands[1]))
1739 operands[1] = legitimize_pic_address (operands[1], QImode, 0);
1741 if (symbolic_operand (operands[1], QImode))
1743 operands[1] = legitimize_pic_address (operands[1],
1745 (reload_in_progress ?
1752 /* All QI constants require only one insn, so proceed. */
1758 (define_insn "*movqi_insn"
1759 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1760 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1761 "(register_operand (operands[0], QImode)
1762 || reg_or_0_operand (operands[1], QImode))"
1767 [(set_attr "type" "*,load,store")
1768 (set_attr "us3load_type" "*,3cycle,*")])
1770 (define_expand "movhi"
1771 [(set (match_operand:HI 0 "general_operand" "")
1772 (match_operand:HI 1 "general_operand" ""))]
1775 /* Working with CONST_INTs is easier, so convert
1776 a double if needed. */
1777 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1778 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1780 /* Handle sets of MEM first. */
1781 if (GET_CODE (operands[0]) == MEM)
1783 if (reg_or_0_operand (operands[1], HImode))
1786 if (! reload_in_progress)
1788 operands[0] = validize_mem (operands[0]);
1789 operands[1] = force_reg (HImode, operands[1]);
1793 /* Fixup TLS cases. */
1794 if (tls_symbolic_operand (operands [1]))
1795 operands[1] = legitimize_tls_address (operands[1]);
1797 /* Fixup PIC cases. */
1800 if (CONSTANT_P (operands[1])
1801 && pic_address_needs_scratch (operands[1]))
1802 operands[1] = legitimize_pic_address (operands[1], HImode, 0);
1804 if (symbolic_operand (operands[1], HImode))
1806 operands[1] = legitimize_pic_address (operands[1],
1808 (reload_in_progress ?
1815 /* This makes sure we will not get rematched due to splittage. */
1816 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
1818 else if (CONSTANT_P (operands[1])
1819 && GET_CODE (operands[1]) != HIGH
1820 && GET_CODE (operands[1]) != LO_SUM)
1822 sparc_emit_set_const32 (operands[0], operands[1]);
1829 (define_insn "*movhi_const64_special"
1830 [(set (match_operand:HI 0 "register_operand" "=r")
1831 (match_operand:HI 1 "const64_high_operand" ""))]
1833 "sethi\t%%hi(%a1), %0")
1835 (define_insn "*movhi_insn"
1836 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1837 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1838 "(register_operand (operands[0], HImode)
1839 || reg_or_0_operand (operands[1], HImode))"
1842 sethi\t%%hi(%a1), %0
1845 [(set_attr "type" "*,*,load,store")
1846 (set_attr "us3load_type" "*,*,3cycle,*")])
1848 ;; We always work with constants here.
1849 (define_insn "*movhi_lo_sum"
1850 [(set (match_operand:HI 0 "register_operand" "=r")
1851 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1852 (match_operand:HI 2 "small_int" "I")))]
1856 (define_expand "movsi"
1857 [(set (match_operand:SI 0 "general_operand" "")
1858 (match_operand:SI 1 "general_operand" ""))]
1861 /* Working with CONST_INTs is easier, so convert
1862 a double if needed. */
1863 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1864 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1866 /* Handle sets of MEM first. */
1867 if (GET_CODE (operands[0]) == MEM)
1869 if (reg_or_0_operand (operands[1], SImode))
1872 if (! reload_in_progress)
1874 operands[0] = validize_mem (operands[0]);
1875 operands[1] = force_reg (SImode, operands[1]);
1879 /* Fixup TLS cases. */
1880 if (tls_symbolic_operand (operands [1]))
1881 operands[1] = legitimize_tls_address (operands[1]);
1883 /* Fixup PIC cases. */
1886 if (CONSTANT_P (operands[1])
1887 && pic_address_needs_scratch (operands[1]))
1888 operands[1] = legitimize_pic_address (operands[1], SImode, 0);
1890 if (GET_CODE (operands[1]) == LABEL_REF)
1893 emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
1897 if (symbolic_operand (operands[1], SImode))
1899 operands[1] = legitimize_pic_address (operands[1],
1901 (reload_in_progress ?
1908 /* If we are trying to toss an integer constant into the
1909 FPU registers, force it into memory. */
1910 if (GET_CODE (operands[0]) == REG
1911 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
1912 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
1913 && CONSTANT_P (operands[1]))
1914 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
1917 /* This makes sure we will not get rematched due to splittage. */
1918 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
1920 else if (CONSTANT_P (operands[1])
1921 && GET_CODE (operands[1]) != HIGH
1922 && GET_CODE (operands[1]) != LO_SUM)
1924 sparc_emit_set_const32 (operands[0], operands[1]);
1931 ;; This is needed to show CSE exactly which bits are set
1932 ;; in a 64-bit register by sethi instructions.
1933 (define_insn "*movsi_const64_special"
1934 [(set (match_operand:SI 0 "register_operand" "=r")
1935 (match_operand:SI 1 "const64_high_operand" ""))]
1937 "sethi\t%%hi(%a1), %0")
1939 (define_insn "*movsi_insn"
1940 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
1941 (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))]
1942 "(register_operand (operands[0], SImode)
1943 || reg_or_0_operand (operands[1], SImode))"
1947 sethi\t%%hi(%a1), %0
1954 [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fga")])
1956 (define_insn "*movsi_lo_sum"
1957 [(set (match_operand:SI 0 "register_operand" "=r")
1958 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1959 (match_operand:SI 2 "immediate_operand" "in")))]
1961 "or\t%1, %%lo(%a2), %0")
1963 (define_insn "*movsi_high"
1964 [(set (match_operand:SI 0 "register_operand" "=r")
1965 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1967 "sethi\t%%hi(%a1), %0")
1969 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1970 ;; so that CSE won't optimize the address computation away.
1971 (define_insn "movsi_lo_sum_pic"
1972 [(set (match_operand:SI 0 "register_operand" "=r")
1973 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1974 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1976 "or\t%1, %%lo(%a2), %0")
1978 (define_insn "movsi_high_pic"
1979 [(set (match_operand:SI 0 "register_operand" "=r")
1980 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1981 "flag_pic && check_pic (1)"
1982 "sethi\t%%hi(%a1), %0")
1984 (define_expand "movsi_pic_label_ref"
1985 [(set (match_dup 3) (high:SI
1986 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1987 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1988 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1989 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1990 (set (match_operand:SI 0 "register_operand" "=r")
1991 (minus:SI (match_dup 5) (match_dup 4)))]
1994 current_function_uses_pic_offset_table = 1;
1995 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1998 operands[3] = operands[0];
1999 operands[4] = operands[0];
2003 operands[3] = gen_reg_rtx (SImode);
2004 operands[4] = gen_reg_rtx (SImode);
2006 operands[5] = pic_offset_table_rtx;
2009 (define_insn "*movsi_high_pic_label_ref"
2010 [(set (match_operand:SI 0 "register_operand" "=r")
2012 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2013 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2015 "sethi\t%%hi(%a2-(%a1-.)), %0")
2017 (define_insn "*movsi_lo_sum_pic_label_ref"
2018 [(set (match_operand:SI 0 "register_operand" "=r")
2019 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2020 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
2021 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2023 "or\t%1, %%lo(%a3-(%a2-.)), %0")
2025 (define_expand "movdi"
2026 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2027 (match_operand:DI 1 "general_operand" ""))]
2030 /* Where possible, convert CONST_DOUBLE into a CONST_INT. */
2031 if (GET_CODE (operands[1]) == CONST_DOUBLE
2032 #if HOST_BITS_PER_WIDE_INT == 32
2033 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2034 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2035 || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2036 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2039 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2041 /* Handle MEM cases first. */
2042 if (GET_CODE (operands[0]) == MEM)
2044 /* If it's a REG, we can always do it.
2045 The const zero case is more complex, on v9
2046 we can always perform it. */
2047 if (register_operand (operands[1], DImode)
2049 && (operands[1] == const0_rtx)))
2052 if (! reload_in_progress)
2054 operands[0] = validize_mem (operands[0]);
2055 operands[1] = force_reg (DImode, operands[1]);
2059 /* Fixup TLS cases. */
2060 if (tls_symbolic_operand (operands [1]))
2061 operands[1] = legitimize_tls_address (operands[1]);
2065 if (CONSTANT_P (operands[1])
2066 && pic_address_needs_scratch (operands[1]))
2067 operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2069 if (GET_CODE (operands[1]) == LABEL_REF)
2071 if (! TARGET_ARCH64)
2073 emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2077 if (symbolic_operand (operands[1], DImode))
2079 operands[1] = legitimize_pic_address (operands[1],
2081 (reload_in_progress ?
2088 /* If we are trying to toss an integer constant into the
2089 FPU registers, force it into memory. */
2090 if (GET_CODE (operands[0]) == REG
2091 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2092 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2093 && CONSTANT_P (operands[1]))
2094 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2097 /* This makes sure we will not get rematched due to splittage. */
2098 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2100 else if (TARGET_ARCH64
2101 && CONSTANT_P (operands[1])
2102 && GET_CODE (operands[1]) != HIGH
2103 && GET_CODE (operands[1]) != LO_SUM)
2105 sparc_emit_set_const64 (operands[0], operands[1]);
2113 ;; Be careful, fmovd does not exist when !v9.
2114 ;; We match MEM moves directly when we have correct even
2115 ;; numbered registers, but fall into splits otherwise.
2116 ;; The constraint ordering here is really important to
2117 ;; avoid insane problems in reload, especially for patterns
2120 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2121 ;; (const_int -5016)))
2125 (define_insn "*movdi_insn_sp32_v9"
2126 [(set (match_operand:DI 0 "nonimmediate_operand"
2127 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
2128 (match_operand:DI 1 "input_operand"
2129 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
2130 "! TARGET_ARCH64 && TARGET_V9
2131 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2148 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
2149 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
2150 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
2152 (define_insn "*movdi_insn_sp32"
2153 [(set (match_operand:DI 0 "nonimmediate_operand"
2154 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2155 (match_operand:DI 1 "input_operand"
2156 " J,U,T,r,o,i,r, f, T, o, f, f"))]
2158 && (register_operand (operands[0], DImode)
2159 || register_operand (operands[1], DImode))"
2173 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2174 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
2176 ;; The following are generated by sparc_emit_set_const64
2177 (define_insn "*movdi_sp64_dbl"
2178 [(set (match_operand:DI 0 "register_operand" "=r")
2179 (match_operand:DI 1 "const64_operand" ""))]
2181 && HOST_BITS_PER_WIDE_INT != 64)"
2184 ;; This is needed to show CSE exactly which bits are set
2185 ;; in a 64-bit register by sethi instructions.
2186 (define_insn "*movdi_const64_special"
2187 [(set (match_operand:DI 0 "register_operand" "=r")
2188 (match_operand:DI 1 "const64_high_operand" ""))]
2190 "sethi\t%%hi(%a1), %0")
2192 (define_insn "*movdi_insn_sp64_novis"
2193 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W")
2194 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e"))]
2195 "TARGET_ARCH64 && ! TARGET_VIS
2196 && (register_operand (operands[0], DImode)
2197 || reg_or_0_operand (operands[1], DImode))"
2200 sethi\t%%hi(%a1), %0
2207 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2208 (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2210 (define_insn "*movdi_insn_sp64_vis"
2211 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W,b")
2212 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e,J"))]
2213 "TARGET_ARCH64 && TARGET_VIS &&
2214 (register_operand (operands[0], DImode)
2215 || reg_or_0_operand (operands[1], DImode))"
2218 sethi\t%%hi(%a1), %0
2226 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fga")
2227 (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2229 (define_expand "movdi_pic_label_ref"
2230 [(set (match_dup 3) (high:DI
2231 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2232 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2233 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2234 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2235 (set (match_operand:DI 0 "register_operand" "=r")
2236 (minus:DI (match_dup 5) (match_dup 4)))]
2237 "TARGET_ARCH64 && flag_pic"
2239 current_function_uses_pic_offset_table = 1;
2240 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
2243 operands[3] = operands[0];
2244 operands[4] = operands[0];
2248 operands[3] = gen_reg_rtx (DImode);
2249 operands[4] = gen_reg_rtx (DImode);
2251 operands[5] = pic_offset_table_rtx;
2254 (define_insn "*movdi_high_pic_label_ref"
2255 [(set (match_operand:DI 0 "register_operand" "=r")
2257 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2258 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2259 "TARGET_ARCH64 && flag_pic"
2260 "sethi\t%%hi(%a2-(%a1-.)), %0")
2262 (define_insn "*movdi_lo_sum_pic_label_ref"
2263 [(set (match_operand:DI 0 "register_operand" "=r")
2264 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2265 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2266 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2267 "TARGET_ARCH64 && flag_pic"
2268 "or\t%1, %%lo(%a3-(%a2-.)), %0")
2270 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
2271 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2273 (define_insn "movdi_lo_sum_pic"
2274 [(set (match_operand:DI 0 "register_operand" "=r")
2275 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2276 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2277 "TARGET_ARCH64 && flag_pic"
2278 "or\t%1, %%lo(%a2), %0")
2280 (define_insn "movdi_high_pic"
2281 [(set (match_operand:DI 0 "register_operand" "=r")
2282 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2283 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2284 "sethi\t%%hi(%a1), %0")
2286 (define_insn "*sethi_di_medlow_embmedany_pic"
2287 [(set (match_operand:DI 0 "register_operand" "=r")
2288 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2289 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2290 "sethi\t%%hi(%a1), %0")
2292 (define_insn "*sethi_di_medlow"
2293 [(set (match_operand:DI 0 "register_operand" "=r")
2294 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2295 "TARGET_CM_MEDLOW && check_pic (1)"
2296 "sethi\t%%hi(%a1), %0")
2298 (define_insn "*losum_di_medlow"
2299 [(set (match_operand:DI 0 "register_operand" "=r")
2300 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2301 (match_operand:DI 2 "symbolic_operand" "")))]
2303 "or\t%1, %%lo(%a2), %0")
2305 (define_insn "seth44"
2306 [(set (match_operand:DI 0 "register_operand" "=r")
2307 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2309 "sethi\t%%h44(%a1), %0")
2311 (define_insn "setm44"
2312 [(set (match_operand:DI 0 "register_operand" "=r")
2313 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2314 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2316 "or\t%1, %%m44(%a2), %0")
2318 (define_insn "setl44"
2319 [(set (match_operand:DI 0 "register_operand" "=r")
2320 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2321 (match_operand:DI 2 "symbolic_operand" "")))]
2323 "or\t%1, %%l44(%a2), %0")
2325 (define_insn "sethh"
2326 [(set (match_operand:DI 0 "register_operand" "=r")
2327 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2329 "sethi\t%%hh(%a1), %0")
2331 (define_insn "setlm"
2332 [(set (match_operand:DI 0 "register_operand" "=r")
2333 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2335 "sethi\t%%lm(%a1), %0")
2337 (define_insn "sethm"
2338 [(set (match_operand:DI 0 "register_operand" "=r")
2339 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2340 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2342 "or\t%1, %%hm(%a2), %0")
2344 (define_insn "setlo"
2345 [(set (match_operand:DI 0 "register_operand" "=r")
2346 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2347 (match_operand:DI 2 "symbolic_operand" "")))]
2349 "or\t%1, %%lo(%a2), %0")
2351 (define_insn "embmedany_sethi"
2352 [(set (match_operand:DI 0 "register_operand" "=r")
2353 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2354 "TARGET_CM_EMBMEDANY && check_pic (1)"
2355 "sethi\t%%hi(%a1), %0")
2357 (define_insn "embmedany_losum"
2358 [(set (match_operand:DI 0 "register_operand" "=r")
2359 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2360 (match_operand:DI 2 "data_segment_operand" "")))]
2361 "TARGET_CM_EMBMEDANY"
2362 "add\t%1, %%lo(%a2), %0")
2364 (define_insn "embmedany_brsum"
2365 [(set (match_operand:DI 0 "register_operand" "=r")
2366 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2367 "TARGET_CM_EMBMEDANY"
2370 (define_insn "embmedany_textuhi"
2371 [(set (match_operand:DI 0 "register_operand" "=r")
2372 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2373 "TARGET_CM_EMBMEDANY && check_pic (1)"
2374 "sethi\t%%uhi(%a1), %0")
2376 (define_insn "embmedany_texthi"
2377 [(set (match_operand:DI 0 "register_operand" "=r")
2378 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2379 "TARGET_CM_EMBMEDANY && check_pic (1)"
2380 "sethi\t%%hi(%a1), %0")
2382 (define_insn "embmedany_textulo"
2383 [(set (match_operand:DI 0 "register_operand" "=r")
2384 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2385 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2386 "TARGET_CM_EMBMEDANY"
2387 "or\t%1, %%ulo(%a2), %0")
2389 (define_insn "embmedany_textlo"
2390 [(set (match_operand:DI 0 "register_operand" "=r")
2391 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2392 (match_operand:DI 2 "text_segment_operand" "")))]
2393 "TARGET_CM_EMBMEDANY"
2394 "or\t%1, %%lo(%a2), %0")
2396 ;; Now some patterns to help reload out a bit.
2397 (define_expand "reload_indi"
2398 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2399 (match_operand:DI 1 "immediate_operand" "")
2400 (match_operand:TI 2 "register_operand" "=&r")])]
2402 || TARGET_CM_EMBMEDANY)
2405 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2409 (define_expand "reload_outdi"
2410 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2411 (match_operand:DI 1 "immediate_operand" "")
2412 (match_operand:TI 2 "register_operand" "=&r")])]
2414 || TARGET_CM_EMBMEDANY)
2417 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2421 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2423 [(set (match_operand:DI 0 "register_operand" "")
2424 (match_operand:DI 1 "const_int_operand" ""))]
2425 "! TARGET_ARCH64 && reload_completed"
2426 [(clobber (const_int 0))]
2428 #if HOST_BITS_PER_WIDE_INT == 32
2429 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2430 (INTVAL (operands[1]) < 0) ?
2433 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2436 unsigned int low, high;
2438 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2439 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2440 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2442 /* Slick... but this trick loses if this subreg constant part
2443 can be done in one insn. */
2444 if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2445 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2446 gen_highpart (SImode, operands[0])));
2448 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2454 [(set (match_operand:DI 0 "register_operand" "")
2455 (match_operand:DI 1 "const_double_operand" ""))]
2459 && ((GET_CODE (operands[0]) == REG
2460 && REGNO (operands[0]) < 32)
2461 || (GET_CODE (operands[0]) == SUBREG
2462 && GET_CODE (SUBREG_REG (operands[0])) == REG
2463 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2464 [(clobber (const_int 0))]
2466 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2467 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2469 /* Slick... but this trick loses if this subreg constant part
2470 can be done in one insn. */
2471 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2472 && !(SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2473 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2475 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2476 gen_highpart (SImode, operands[0])));
2480 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2481 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2487 [(set (match_operand:DI 0 "register_operand" "")
2488 (match_operand:DI 1 "register_operand" ""))]
2492 && ((GET_CODE (operands[0]) == REG
2493 && REGNO (operands[0]) < 32)
2494 || (GET_CODE (operands[0]) == SUBREG
2495 && GET_CODE (SUBREG_REG (operands[0])) == REG
2496 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2497 [(clobber (const_int 0))]
2499 rtx set_dest = operands[0];
2500 rtx set_src = operands[1];
2504 dest1 = gen_highpart (SImode, set_dest);
2505 dest2 = gen_lowpart (SImode, set_dest);
2506 src1 = gen_highpart (SImode, set_src);
2507 src2 = gen_lowpart (SImode, set_src);
2509 /* Now emit using the real source and destination we found, swapping
2510 the order if we detect overlap. */
2511 if (reg_overlap_mentioned_p (dest1, src2))
2513 emit_insn (gen_movsi (dest2, src2));
2514 emit_insn (gen_movsi (dest1, src1));
2518 emit_insn (gen_movsi (dest1, src1));
2519 emit_insn (gen_movsi (dest2, src2));
2524 ;; Now handle the cases of memory moves from/to non-even
2525 ;; DI mode register pairs.
2527 [(set (match_operand:DI 0 "register_operand" "")
2528 (match_operand:DI 1 "memory_operand" ""))]
2531 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2532 [(clobber (const_int 0))]
2534 rtx word0 = adjust_address (operands[1], SImode, 0);
2535 rtx word1 = adjust_address (operands[1], SImode, 4);
2536 rtx high_part = gen_highpart (SImode, operands[0]);
2537 rtx low_part = gen_lowpart (SImode, operands[0]);
2539 if (reg_overlap_mentioned_p (high_part, word1))
2541 emit_insn (gen_movsi (low_part, word1));
2542 emit_insn (gen_movsi (high_part, word0));
2546 emit_insn (gen_movsi (high_part, word0));
2547 emit_insn (gen_movsi (low_part, word1));
2553 [(set (match_operand:DI 0 "memory_operand" "")
2554 (match_operand:DI 1 "register_operand" ""))]
2557 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2558 [(clobber (const_int 0))]
2560 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2561 gen_highpart (SImode, operands[1])));
2562 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2563 gen_lowpart (SImode, operands[1])));
2568 [(set (match_operand:DI 0 "memory_operand" "")
2573 && ! mem_min_alignment (operands[0], 8)))
2574 && offsettable_memref_p (operands[0])"
2575 [(clobber (const_int 0))]
2577 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2578 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2582 ;; Floating point move insns
2584 (define_insn "*movsf_insn_novis"
2585 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2586 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
2587 "(TARGET_FPU && ! TARGET_VIS)
2588 && (register_operand (operands[0], SFmode)
2589 || register_operand (operands[1], SFmode)
2590 || fp_zero_operand (operands[1], SFmode))"
2592 if (GET_CODE (operands[1]) == CONST_DOUBLE
2593 && (which_alternative == 2
2594 || which_alternative == 3
2595 || which_alternative == 4))
2600 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2601 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2602 operands[1] = GEN_INT (i);
2605 switch (which_alternative)
2608 return "fmovs\t%1, %0";
2612 return "sethi\t%%hi(%a1), %0";
2614 return "mov\t%1, %0";
2619 return "ld\t%1, %0";
2622 return "st\t%r1, %0";
2627 [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
2629 (define_insn "*movsf_insn_vis"
2630 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
2631 (match_operand:SF 1 "input_operand" "f,G,G,Q,*rR,S,m,m,f,*rG"))]
2632 "(TARGET_FPU && TARGET_VIS)
2633 && (register_operand (operands[0], SFmode)
2634 || register_operand (operands[1], SFmode)
2635 || fp_zero_operand (operands[1], SFmode))"
2637 if (GET_CODE (operands[1]) == CONST_DOUBLE
2638 && (which_alternative == 3
2639 || which_alternative == 4
2640 || which_alternative == 5))
2645 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2646 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2647 operands[1] = GEN_INT (i);
2650 switch (which_alternative)
2653 return "fmovs\t%1, %0";
2655 return "fzeros\t%0";
2659 return "sethi\t%%hi(%a1), %0";
2661 return "mov\t%1, %0";
2666 return "ld\t%1, %0";
2669 return "st\t%r1, %0";
2674 [(set_attr "type" "fpmove,fga,*,*,*,*,load,fpload,fpstore,store")])
2676 ;; Exactly the same as above, except that all `f' cases are deleted.
2677 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2680 (define_insn "*movsf_no_f_insn"
2681 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
2682 (match_operand:SF 1 "input_operand" "G,Q,rR,S,m,rG"))]
2684 && (register_operand (operands[0], SFmode)
2685 || register_operand (operands[1], SFmode)
2686 || fp_zero_operand (operands[1], SFmode))"
2688 if (GET_CODE (operands[1]) == CONST_DOUBLE
2689 && (which_alternative == 1
2690 || which_alternative == 2
2691 || which_alternative == 3))
2696 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2697 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2698 operands[1] = GEN_INT (i);
2701 switch (which_alternative)
2706 return "sethi\t%%hi(%a1), %0";
2708 return "mov\t%1, %0";
2712 return "ld\t%1, %0";
2714 return "st\t%r1, %0";
2719 [(set_attr "type" "*,*,*,*,load,store")])
2721 (define_insn "*movsf_lo_sum"
2722 [(set (match_operand:SF 0 "register_operand" "=r")
2723 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2724 (match_operand:SF 2 "const_double_operand" "S")))]
2725 "fp_high_losum_p (operands[2])"
2730 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2731 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2732 operands[2] = GEN_INT (i);
2733 return "or\t%1, %%lo(%a2), %0";
2736 (define_insn "*movsf_high"
2737 [(set (match_operand:SF 0 "register_operand" "=r")
2738 (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
2739 "fp_high_losum_p (operands[1])"
2744 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2745 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2746 operands[1] = GEN_INT (i);
2747 return "sethi\t%%hi(%1), %0";
2751 [(set (match_operand:SF 0 "register_operand" "")
2752 (match_operand:SF 1 "const_double_operand" ""))]
2753 "fp_high_losum_p (operands[1])
2754 && (GET_CODE (operands[0]) == REG
2755 && REGNO (operands[0]) < 32)"
2756 [(set (match_dup 0) (high:SF (match_dup 1)))
2757 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2759 (define_expand "movsf"
2760 [(set (match_operand:SF 0 "general_operand" "")
2761 (match_operand:SF 1 "general_operand" ""))]
2764 /* Force SFmode constants into memory. */
2765 if (GET_CODE (operands[0]) == REG
2766 && CONSTANT_P (operands[1]))
2768 /* emit_group_store will send such bogosity to us when it is
2769 not storing directly into memory. So fix this up to avoid
2770 crashes in output_constant_pool. */
2771 if (operands [1] == const0_rtx)
2772 operands[1] = CONST0_RTX (SFmode);
2774 if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
2777 /* We are able to build any SF constant in integer registers
2778 with at most 2 instructions. */
2779 if (REGNO (operands[0]) < 32)
2782 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2786 /* Handle sets of MEM first. */
2787 if (GET_CODE (operands[0]) == MEM)
2789 if (register_operand (operands[1], SFmode)
2790 || fp_zero_operand (operands[1], SFmode))
2793 if (! reload_in_progress)
2795 operands[0] = validize_mem (operands[0]);
2796 operands[1] = force_reg (SFmode, operands[1]);
2800 /* Fixup PIC cases. */
2803 if (CONSTANT_P (operands[1])
2804 && pic_address_needs_scratch (operands[1]))
2805 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
2807 if (symbolic_operand (operands[1], SFmode))
2809 operands[1] = legitimize_pic_address (operands[1],
2811 (reload_in_progress ?
2821 (define_expand "movdf"
2822 [(set (match_operand:DF 0 "general_operand" "")
2823 (match_operand:DF 1 "general_operand" ""))]
2826 /* Force DFmode constants into memory. */
2827 if (GET_CODE (operands[0]) == REG
2828 && CONSTANT_P (operands[1]))
2830 /* emit_group_store will send such bogosity to us when it is
2831 not storing directly into memory. So fix this up to avoid
2832 crashes in output_constant_pool. */
2833 if (operands [1] == const0_rtx)
2834 operands[1] = CONST0_RTX (DFmode);
2836 if ((TARGET_VIS || REGNO (operands[0]) < 32)
2837 && fp_zero_operand (operands[1], DFmode))
2840 /* We are able to build any DF constant in integer registers. */
2841 if (REGNO (operands[0]) < 32
2842 && (reload_completed || reload_in_progress))
2845 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2849 /* Handle MEM cases first. */
2850 if (GET_CODE (operands[0]) == MEM)
2852 if (register_operand (operands[1], DFmode)
2853 || fp_zero_operand (operands[1], DFmode))
2856 if (! reload_in_progress)
2858 operands[0] = validize_mem (operands[0]);
2859 operands[1] = force_reg (DFmode, operands[1]);
2863 /* Fixup PIC cases. */
2866 if (CONSTANT_P (operands[1])
2867 && pic_address_needs_scratch (operands[1]))
2868 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
2870 if (symbolic_operand (operands[1], DFmode))
2872 operands[1] = legitimize_pic_address (operands[1],
2874 (reload_in_progress ?
2884 ;; Be careful, fmovd does not exist when !v9.
2885 (define_insn "*movdf_insn_sp32"
2886 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2887 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2890 && (register_operand (operands[0], DFmode)
2891 || register_operand (operands[1], DFmode)
2892 || fp_zero_operand (operands[1], DFmode))"
2904 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2905 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2907 (define_insn "*movdf_no_e_insn_sp32"
2908 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2909 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2913 && (register_operand (operands[0], DFmode)
2914 || register_operand (operands[1], DFmode)
2915 || fp_zero_operand (operands[1], DFmode))"
2922 [(set_attr "type" "load,store,*,*,*")
2923 (set_attr "length" "*,*,2,2,2")])
2925 (define_insn "*movdf_no_e_insn_v9_sp32"
2926 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2927 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2931 && (register_operand (operands[0], DFmode)
2932 || register_operand (operands[1], DFmode)
2933 || fp_zero_operand (operands[1], DFmode))"
2940 [(set_attr "type" "load,store,store,*,*")
2941 (set_attr "length" "*,*,*,2,2")])
2943 ;; We have available v9 double floats but not 64-bit
2944 ;; integer registers and no VIS.
2945 (define_insn "*movdf_insn_v9only_novis"
2946 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,W,U,T,f,*r,o")
2947 (match_operand:DF 1 "input_operand" "e,W#F,G,e,T,U,o#F,*roF,*rGf"))]
2952 && (register_operand (operands[0], DFmode)
2953 || register_operand (operands[1], DFmode)
2954 || fp_zero_operand (operands[1], DFmode))"
2965 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
2966 (set_attr "length" "*,*,*,*,*,*,2,2,2")
2967 (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
2969 ;; We have available v9 double floats but not 64-bit
2970 ;; integer registers but we have VIS.
2971 (define_insn "*movdf_insn_v9only_vis"
2972 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,W,U,T,f,*r,o")
2973 (match_operand:DF 1 "input_operand" "G,e,W#F,G,e,T,U,o#F,*roGF,*rGf"))]
2977 && (register_operand (operands[0], DFmode)
2978 || register_operand (operands[1], DFmode)
2979 || fp_zero_operand (operands[1], DFmode))"
2991 [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
2992 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2993 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2995 ;; We have available both v9 double floats and 64-bit
2996 ;; integer registers. No VIS though.
2997 (define_insn "*movdf_insn_sp64_novis"
2998 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,W,*r,*r,m,*r")
2999 (match_operand:DF 1 "input_operand" "e,W#F,e,*rG,m,*rG,F"))]
3003 && (register_operand (operands[0], DFmode)
3004 || register_operand (operands[1], DFmode)
3005 || fp_zero_operand (operands[1], DFmode))"
3014 [(set_attr "type" "fpmove,load,store,*,load,store,*")
3015 (set_attr "length" "*,*,*,*,*,*,2")
3016 (set_attr "fptype" "double,*,*,*,*,*,*")])
3018 ;; We have available both v9 double floats and 64-bit
3019 ;; integer registers. And we have VIS.
3020 (define_insn "*movdf_insn_sp64_vis"
3021 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,W,*r,*r,m,*r")
3022 (match_operand:DF 1 "input_operand" "G,e,W#F,e,*rG,m,*rG,F"))]
3026 && (register_operand (operands[0], DFmode)
3027 || register_operand (operands[1], DFmode)
3028 || fp_zero_operand (operands[1], DFmode))"
3038 [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
3039 (set_attr "length" "*,*,*,*,*,*,*,2")
3040 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3042 (define_insn "*movdf_no_e_insn_sp64"
3043 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3044 (match_operand:DF 1 "input_operand" "r,m,rG"))]
3047 && (register_operand (operands[0], DFmode)
3048 || register_operand (operands[1], DFmode)
3049 || fp_zero_operand (operands[1], DFmode))"
3054 [(set_attr "type" "*,load,store")])
3057 [(set (match_operand:DF 0 "register_operand" "")
3058 (match_operand:DF 1 "const_double_operand" ""))]
3060 && (GET_CODE (operands[0]) == REG
3061 && REGNO (operands[0]) < 32)
3062 && ! fp_zero_operand(operands[1], DFmode)
3063 && reload_completed"
3064 [(clobber (const_int 0))]
3069 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3070 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3071 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3075 #if HOST_BITS_PER_WIDE_INT == 64
3078 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3079 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3080 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3082 emit_insn (gen_movdi (operands[0],
3083 immed_double_const (l[1], l[0], DImode)));
3088 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3091 /* Slick... but this trick loses if this subreg constant part
3092 can be done in one insn. */
3094 && !(SPARC_SETHI32_P (l[0])
3095 || SPARC_SIMM13_P (l[0])))
3097 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3098 gen_highpart (SImode, operands[0])));
3102 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3109 ;; Ok, now the splits to handle all the multi insn and
3110 ;; mis-aligned memory address cases.
3111 ;; In these splits please take note that we must be
3112 ;; careful when V9 but not ARCH64 because the integer
3113 ;; register DFmode cases must be handled.
3115 [(set (match_operand:DF 0 "register_operand" "")
3116 (match_operand:DF 1 "register_operand" ""))]
3119 && ((GET_CODE (operands[0]) == REG
3120 && REGNO (operands[0]) < 32)
3121 || (GET_CODE (operands[0]) == SUBREG
3122 && GET_CODE (SUBREG_REG (operands[0])) == REG
3123 && REGNO (SUBREG_REG (operands[0])) < 32))))
3124 && reload_completed"
3125 [(clobber (const_int 0))]
3127 rtx set_dest = operands[0];
3128 rtx set_src = operands[1];
3132 dest1 = gen_highpart (SFmode, set_dest);
3133 dest2 = gen_lowpart (SFmode, set_dest);
3134 src1 = gen_highpart (SFmode, set_src);
3135 src2 = gen_lowpart (SFmode, set_src);
3137 /* Now emit using the real source and destination we found, swapping
3138 the order if we detect overlap. */
3139 if (reg_overlap_mentioned_p (dest1, src2))
3141 emit_insn (gen_movsf (dest2, src2));
3142 emit_insn (gen_movsf (dest1, src1));
3146 emit_insn (gen_movsf (dest1, src1));
3147 emit_insn (gen_movsf (dest2, src2));
3153 [(set (match_operand:DF 0 "register_operand" "")
3154 (match_operand:DF 1 "memory_operand" ""))]
3157 && (((REGNO (operands[0]) % 2) != 0)
3158 || ! mem_min_alignment (operands[1], 8))
3159 && offsettable_memref_p (operands[1])"
3160 [(clobber (const_int 0))]
3162 rtx word0 = adjust_address (operands[1], SFmode, 0);
3163 rtx word1 = adjust_address (operands[1], SFmode, 4);
3165 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3167 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3169 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3174 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3176 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3183 [(set (match_operand:DF 0 "memory_operand" "")
3184 (match_operand:DF 1 "register_operand" ""))]
3187 && (((REGNO (operands[1]) % 2) != 0)
3188 || ! mem_min_alignment (operands[0], 8))
3189 && offsettable_memref_p (operands[0])"
3190 [(clobber (const_int 0))]
3192 rtx word0 = adjust_address (operands[0], SFmode, 0);
3193 rtx word1 = adjust_address (operands[0], SFmode, 4);
3195 emit_insn (gen_movsf (word0,
3196 gen_highpart (SFmode, operands[1])));
3197 emit_insn (gen_movsf (word1,
3198 gen_lowpart (SFmode, operands[1])));
3203 [(set (match_operand:DF 0 "memory_operand" "")
3204 (match_operand:DF 1 "fp_zero_operand" ""))]
3208 && ! mem_min_alignment (operands[0], 8)))
3209 && offsettable_memref_p (operands[0])"
3210 [(clobber (const_int 0))]
3214 dest1 = adjust_address (operands[0], SFmode, 0);
3215 dest2 = adjust_address (operands[0], SFmode, 4);
3217 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3218 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3223 [(set (match_operand:DF 0 "register_operand" "")
3224 (match_operand:DF 1 "fp_zero_operand" ""))]
3227 && ((GET_CODE (operands[0]) == REG
3228 && REGNO (operands[0]) < 32)
3229 || (GET_CODE (operands[0]) == SUBREG
3230 && GET_CODE (SUBREG_REG (operands[0])) == REG
3231 && REGNO (SUBREG_REG (operands[0])) < 32))"
3232 [(clobber (const_int 0))]
3234 rtx set_dest = operands[0];
3237 dest1 = gen_highpart (SFmode, set_dest);
3238 dest2 = gen_lowpart (SFmode, set_dest);
3239 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3240 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3244 (define_expand "movtf"
3245 [(set (match_operand:TF 0 "general_operand" "")
3246 (match_operand:TF 1 "general_operand" ""))]
3249 /* Force TFmode constants into memory. */
3250 if (GET_CODE (operands[0]) == REG
3251 && CONSTANT_P (operands[1]))
3253 /* emit_group_store will send such bogosity to us when it is
3254 not storing directly into memory. So fix this up to avoid
3255 crashes in output_constant_pool. */
3256 if (operands [1] == const0_rtx)
3257 operands[1] = CONST0_RTX (TFmode);
3259 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3262 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3266 /* Handle MEM cases first, note that only v9 guarantees
3267 full 16-byte alignment for quads. */
3268 if (GET_CODE (operands[0]) == MEM)
3270 if (register_operand (operands[1], TFmode)
3271 || fp_zero_operand (operands[1], TFmode))
3274 if (! reload_in_progress)
3276 operands[0] = validize_mem (operands[0]);
3277 operands[1] = force_reg (TFmode, operands[1]);
3281 /* Fixup PIC cases. */
3284 if (CONSTANT_P (operands[1])
3285 && pic_address_needs_scratch (operands[1]))
3286 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3288 if (symbolic_operand (operands[1], TFmode))
3290 operands[1] = legitimize_pic_address (operands[1],
3292 (reload_in_progress ?
3302 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3303 ;; we must split them all. :-(
3304 (define_insn "*movtf_insn_sp32"
3305 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3306 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
3310 && (register_operand (operands[0], TFmode)
3311 || register_operand (operands[1], TFmode)
3312 || fp_zero_operand (operands[1], TFmode))"
3314 [(set_attr "length" "4")])
3316 (define_insn "*movtf_insn_vis_sp32"
3317 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3318 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3322 && (register_operand (operands[0], TFmode)
3323 || register_operand (operands[1], TFmode)
3324 || fp_zero_operand (operands[1], TFmode))"
3326 [(set_attr "length" "4")])
3328 ;; Exactly the same as above, except that all `e' cases are deleted.
3329 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3332 (define_insn "*movtf_no_e_insn_sp32"
3333 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3334 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3337 && (register_operand (operands[0], TFmode)
3338 || register_operand (operands[1], TFmode)
3339 || fp_zero_operand (operands[1], TFmode))"
3341 [(set_attr "length" "4")])
3343 ;; Now handle the float reg cases directly when arch64,
3344 ;; hard_quad, and proper reg number alignment are all true.
3345 (define_insn "*movtf_insn_hq_sp64"
3346 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3347 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3352 && (register_operand (operands[0], TFmode)
3353 || register_operand (operands[1], TFmode)
3354 || fp_zero_operand (operands[1], TFmode))"
3361 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3362 (set_attr "length" "*,*,*,2,2")])
3364 (define_insn "*movtf_insn_hq_vis_sp64"
3365 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3366 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3371 && (register_operand (operands[0], TFmode)
3372 || register_operand (operands[1], TFmode)
3373 || fp_zero_operand (operands[1], TFmode))"
3381 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3382 (set_attr "length" "*,*,*,2,2,2")])
3384 ;; Now we allow the integer register cases even when
3385 ;; only arch64 is true.
3386 (define_insn "*movtf_insn_sp64"
3387 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3388 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3392 && ! TARGET_HARD_QUAD
3393 && (register_operand (operands[0], TFmode)
3394 || register_operand (operands[1], TFmode)
3395 || fp_zero_operand (operands[1], TFmode))"
3397 [(set_attr "length" "2")])
3399 (define_insn "*movtf_insn_vis_sp64"
3400 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3401 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
3405 && ! TARGET_HARD_QUAD
3406 && (register_operand (operands[0], TFmode)
3407 || register_operand (operands[1], TFmode)
3408 || fp_zero_operand (operands[1], TFmode))"
3410 [(set_attr "length" "2")])
3412 (define_insn "*movtf_no_e_insn_sp64"
3413 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3414 (match_operand:TF 1 "input_operand" "orG,rG"))]
3417 && (register_operand (operands[0], TFmode)
3418 || register_operand (operands[1], TFmode)
3419 || fp_zero_operand (operands[1], TFmode))"
3421 [(set_attr "length" "2")])
3423 ;; Now all the splits to handle multi-insn TF mode moves.
3425 [(set (match_operand:TF 0 "register_operand" "")
3426 (match_operand:TF 1 "register_operand" ""))]
3430 && ! TARGET_HARD_QUAD)
3431 || ! fp_register_operand (operands[0], TFmode))"
3432 [(clobber (const_int 0))]
3434 rtx set_dest = operands[0];
3435 rtx set_src = operands[1];
3439 dest1 = gen_df_reg (set_dest, 0);
3440 dest2 = gen_df_reg (set_dest, 1);
3441 src1 = gen_df_reg (set_src, 0);
3442 src2 = gen_df_reg (set_src, 1);
3444 /* Now emit using the real source and destination we found, swapping
3445 the order if we detect overlap. */
3446 if (reg_overlap_mentioned_p (dest1, src2))
3448 emit_insn (gen_movdf (dest2, src2));
3449 emit_insn (gen_movdf (dest1, src1));
3453 emit_insn (gen_movdf (dest1, src1));
3454 emit_insn (gen_movdf (dest2, src2));
3460 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3461 (match_operand:TF 1 "fp_zero_operand" ""))]
3463 [(clobber (const_int 0))]
3465 rtx set_dest = operands[0];
3468 switch (GET_CODE (set_dest))
3471 dest1 = gen_df_reg (set_dest, 0);
3472 dest2 = gen_df_reg (set_dest, 1);
3475 dest1 = adjust_address (set_dest, DFmode, 0);
3476 dest2 = adjust_address (set_dest, DFmode, 8);
3482 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3483 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3488 [(set (match_operand:TF 0 "register_operand" "")
3489 (match_operand:TF 1 "memory_operand" ""))]
3491 && offsettable_memref_p (operands[1])
3493 || ! TARGET_HARD_QUAD
3494 || ! fp_register_operand (operands[0], TFmode)))"
3495 [(clobber (const_int 0))]
3497 rtx word0 = adjust_address (operands[1], DFmode, 0);
3498 rtx word1 = adjust_address (operands[1], DFmode, 8);
3499 rtx set_dest, dest1, dest2;
3501 set_dest = operands[0];
3503 dest1 = gen_df_reg (set_dest, 0);
3504 dest2 = gen_df_reg (set_dest, 1);
3506 /* Now output, ordering such that we don't clobber any registers
3507 mentioned in the address. */
3508 if (reg_overlap_mentioned_p (dest1, word1))
3511 emit_insn (gen_movdf (dest2, word1));
3512 emit_insn (gen_movdf (dest1, word0));
3516 emit_insn (gen_movdf (dest1, word0));
3517 emit_insn (gen_movdf (dest2, word1));
3523 [(set (match_operand:TF 0 "memory_operand" "")
3524 (match_operand:TF 1 "register_operand" ""))]
3526 && offsettable_memref_p (operands[0])
3528 || ! TARGET_HARD_QUAD
3529 || ! fp_register_operand (operands[1], TFmode)))"
3530 [(clobber (const_int 0))]
3532 rtx set_src = operands[1];
3534 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3535 gen_df_reg (set_src, 0)));
3536 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3537 gen_df_reg (set_src, 1)));
3541 ;; SPARC V9 conditional move instructions.
3543 ;; We can handle larger constants here for some flavors, but for now we keep
3544 ;; it simple and only allow those constants supported by all flavors.
3545 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3546 ;; 3 contains the constant if one is present, but we handle either for
3547 ;; generality (sparc.c puts a constant in operand 2).
3549 (define_expand "movqicc"
3550 [(set (match_operand:QI 0 "register_operand" "")
3551 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3552 (match_operand:QI 2 "arith10_operand" "")
3553 (match_operand:QI 3 "arith10_operand" "")))]
3556 enum rtx_code code = GET_CODE (operands[1]);
3558 if (GET_MODE (sparc_compare_op0) == DImode
3562 if (sparc_compare_op1 == const0_rtx
3563 && GET_CODE (sparc_compare_op0) == REG
3564 && GET_MODE (sparc_compare_op0) == DImode
3565 && v9_regcmp_p (code))
3567 operands[1] = gen_rtx_fmt_ee (code, DImode,
3568 sparc_compare_op0, sparc_compare_op1);
3572 rtx cc_reg = gen_compare_reg (code,
3573 sparc_compare_op0, sparc_compare_op1);
3574 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3578 (define_expand "movhicc"
3579 [(set (match_operand:HI 0 "register_operand" "")
3580 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3581 (match_operand:HI 2 "arith10_operand" "")
3582 (match_operand:HI 3 "arith10_operand" "")))]
3585 enum rtx_code code = GET_CODE (operands[1]);
3587 if (GET_MODE (sparc_compare_op0) == DImode
3591 if (sparc_compare_op1 == const0_rtx
3592 && GET_CODE (sparc_compare_op0) == REG
3593 && GET_MODE (sparc_compare_op0) == DImode
3594 && v9_regcmp_p (code))
3596 operands[1] = gen_rtx_fmt_ee (code, DImode,
3597 sparc_compare_op0, sparc_compare_op1);
3601 rtx cc_reg = gen_compare_reg (code,
3602 sparc_compare_op0, sparc_compare_op1);
3603 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3607 (define_expand "movsicc"
3608 [(set (match_operand:SI 0 "register_operand" "")
3609 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3610 (match_operand:SI 2 "arith10_operand" "")
3611 (match_operand:SI 3 "arith10_operand" "")))]
3614 enum rtx_code code = GET_CODE (operands[1]);
3615 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3617 if (sparc_compare_op1 == const0_rtx
3618 && GET_CODE (sparc_compare_op0) == REG
3619 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3621 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3622 sparc_compare_op0, sparc_compare_op1);
3626 rtx cc_reg = gen_compare_reg (code,
3627 sparc_compare_op0, sparc_compare_op1);
3628 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3629 cc_reg, const0_rtx);
3633 (define_expand "movdicc"
3634 [(set (match_operand:DI 0 "register_operand" "")
3635 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3636 (match_operand:DI 2 "arith10_double_operand" "")
3637 (match_operand:DI 3 "arith10_double_operand" "")))]
3640 enum rtx_code code = GET_CODE (operands[1]);
3642 if (sparc_compare_op1 == const0_rtx
3643 && GET_CODE (sparc_compare_op0) == REG
3644 && GET_MODE (sparc_compare_op0) == DImode
3645 && v9_regcmp_p (code))
3647 operands[1] = gen_rtx_fmt_ee (code, DImode,
3648 sparc_compare_op0, sparc_compare_op1);
3652 rtx cc_reg = gen_compare_reg (code,
3653 sparc_compare_op0, sparc_compare_op1);
3654 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3655 cc_reg, const0_rtx);
3659 (define_expand "movsfcc"
3660 [(set (match_operand:SF 0 "register_operand" "")
3661 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3662 (match_operand:SF 2 "register_operand" "")
3663 (match_operand:SF 3 "register_operand" "")))]
3664 "TARGET_V9 && TARGET_FPU"
3666 enum rtx_code code = GET_CODE (operands[1]);
3668 if (GET_MODE (sparc_compare_op0) == DImode
3672 if (sparc_compare_op1 == const0_rtx
3673 && GET_CODE (sparc_compare_op0) == REG
3674 && GET_MODE (sparc_compare_op0) == DImode
3675 && v9_regcmp_p (code))
3677 operands[1] = gen_rtx_fmt_ee (code, DImode,
3678 sparc_compare_op0, sparc_compare_op1);
3682 rtx cc_reg = gen_compare_reg (code,
3683 sparc_compare_op0, sparc_compare_op1);
3684 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3688 (define_expand "movdfcc"
3689 [(set (match_operand:DF 0 "register_operand" "")
3690 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3691 (match_operand:DF 2 "register_operand" "")
3692 (match_operand:DF 3 "register_operand" "")))]
3693 "TARGET_V9 && TARGET_FPU"
3695 enum rtx_code code = GET_CODE (operands[1]);
3697 if (GET_MODE (sparc_compare_op0) == DImode
3701 if (sparc_compare_op1 == const0_rtx
3702 && GET_CODE (sparc_compare_op0) == REG
3703 && GET_MODE (sparc_compare_op0) == DImode
3704 && v9_regcmp_p (code))
3706 operands[1] = gen_rtx_fmt_ee (code, DImode,
3707 sparc_compare_op0, sparc_compare_op1);
3711 rtx cc_reg = gen_compare_reg (code,
3712 sparc_compare_op0, sparc_compare_op1);
3713 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3717 (define_expand "movtfcc"
3718 [(set (match_operand:TF 0 "register_operand" "")
3719 (if_then_else:TF (match_operand 1 "comparison_operator" "")
3720 (match_operand:TF 2 "register_operand" "")
3721 (match_operand:TF 3 "register_operand" "")))]
3722 "TARGET_V9 && TARGET_FPU"
3724 enum rtx_code code = GET_CODE (operands[1]);
3726 if (GET_MODE (sparc_compare_op0) == DImode
3730 if (sparc_compare_op1 == const0_rtx
3731 && GET_CODE (sparc_compare_op0) == REG
3732 && GET_MODE (sparc_compare_op0) == DImode
3733 && v9_regcmp_p (code))
3735 operands[1] = gen_rtx_fmt_ee (code, DImode,
3736 sparc_compare_op0, sparc_compare_op1);
3740 rtx cc_reg = gen_compare_reg (code,
3741 sparc_compare_op0, sparc_compare_op1);
3742 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3746 ;; Conditional move define_insns.
3748 (define_insn "*movqi_cc_sp64"
3749 [(set (match_operand:QI 0 "register_operand" "=r,r")
3750 (if_then_else:QI (match_operator 1 "comparison_operator"
3751 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3753 (match_operand:QI 3 "arith11_operand" "rL,0")
3754 (match_operand:QI 4 "arith11_operand" "0,rL")))]
3758 mov%c1\t%x2, %4, %0"
3759 [(set_attr "type" "cmove")])
3761 (define_insn "*movhi_cc_sp64"
3762 [(set (match_operand:HI 0 "register_operand" "=r,r")
3763 (if_then_else:HI (match_operator 1 "comparison_operator"
3764 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3766 (match_operand:HI 3 "arith11_operand" "rL,0")
3767 (match_operand:HI 4 "arith11_operand" "0,rL")))]
3771 mov%c1\t%x2, %4, %0"
3772 [(set_attr "type" "cmove")])
3774 (define_insn "*movsi_cc_sp64"
3775 [(set (match_operand:SI 0 "register_operand" "=r,r")
3776 (if_then_else:SI (match_operator 1 "comparison_operator"
3777 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3779 (match_operand:SI 3 "arith11_operand" "rL,0")
3780 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3784 mov%c1\t%x2, %4, %0"
3785 [(set_attr "type" "cmove")])
3787 ;; ??? The constraints of operands 3,4 need work.
3788 (define_insn "*movdi_cc_sp64"
3789 [(set (match_operand:DI 0 "register_operand" "=r,r")
3790 (if_then_else:DI (match_operator 1 "comparison_operator"
3791 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3793 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
3794 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
3798 mov%c1\t%x2, %4, %0"
3799 [(set_attr "type" "cmove")])
3801 (define_insn "*movdi_cc_sp64_trunc"
3802 [(set (match_operand:SI 0 "register_operand" "=r,r")
3803 (if_then_else:SI (match_operator 1 "comparison_operator"
3804 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3806 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
3807 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
3811 mov%c1\t%x2, %4, %0"
3812 [(set_attr "type" "cmove")])
3814 (define_insn "*movsf_cc_sp64"
3815 [(set (match_operand:SF 0 "register_operand" "=f,f")
3816 (if_then_else:SF (match_operator 1 "comparison_operator"
3817 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3819 (match_operand:SF 3 "register_operand" "f,0")
3820 (match_operand:SF 4 "register_operand" "0,f")))]
3821 "TARGET_V9 && TARGET_FPU"
3823 fmovs%C1\t%x2, %3, %0
3824 fmovs%c1\t%x2, %4, %0"
3825 [(set_attr "type" "fpcmove")])
3827 (define_insn "movdf_cc_sp64"
3828 [(set (match_operand:DF 0 "register_operand" "=e,e")
3829 (if_then_else:DF (match_operator 1 "comparison_operator"
3830 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3832 (match_operand:DF 3 "register_operand" "e,0")
3833 (match_operand:DF 4 "register_operand" "0,e")))]
3834 "TARGET_V9 && TARGET_FPU"
3836 fmovd%C1\t%x2, %3, %0
3837 fmovd%c1\t%x2, %4, %0"
3838 [(set_attr "type" "fpcmove")
3839 (set_attr "fptype" "double")])
3841 (define_insn "*movtf_cc_hq_sp64"
3842 [(set (match_operand:TF 0 "register_operand" "=e,e")
3843 (if_then_else:TF (match_operator 1 "comparison_operator"
3844 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3846 (match_operand:TF 3 "register_operand" "e,0")
3847 (match_operand:TF 4 "register_operand" "0,e")))]
3848 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3850 fmovq%C1\t%x2, %3, %0
3851 fmovq%c1\t%x2, %4, %0"
3852 [(set_attr "type" "fpcmove")])
3854 (define_insn_and_split "*movtf_cc_sp64"
3855 [(set (match_operand:TF 0 "register_operand" "=e,e")
3856 (if_then_else:TF (match_operator 1 "comparison_operator"
3857 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3859 (match_operand:TF 3 "register_operand" "e,0")
3860 (match_operand:TF 4 "register_operand" "0,e")))]
3861 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3863 "&& reload_completed"
3864 [(clobber (const_int 0))]
3866 rtx set_dest = operands[0];
3867 rtx set_srca = operands[3];
3868 rtx set_srcb = operands[4];
3869 int third = rtx_equal_p (set_dest, set_srca);
3871 rtx srca1, srca2, srcb1, srcb2;
3873 dest1 = gen_df_reg (set_dest, 0);
3874 dest2 = gen_df_reg (set_dest, 1);
3875 srca1 = gen_df_reg (set_srca, 0);
3876 srca2 = gen_df_reg (set_srca, 1);
3877 srcb1 = gen_df_reg (set_srcb, 0);
3878 srcb2 = gen_df_reg (set_srcb, 1);
3880 /* Now emit using the real source and destination we found, swapping
3881 the order if we detect overlap. */
3882 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3883 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3885 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3886 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3890 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3891 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3895 [(set_attr "length" "2")])
3897 (define_insn "*movqi_cc_reg_sp64"
3898 [(set (match_operand:QI 0 "register_operand" "=r,r")
3899 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
3900 [(match_operand:DI 2 "register_operand" "r,r")
3902 (match_operand:QI 3 "arith10_operand" "rM,0")
3903 (match_operand:QI 4 "arith10_operand" "0,rM")))]
3906 movr%D1\t%2, %r3, %0
3907 movr%d1\t%2, %r4, %0"
3908 [(set_attr "type" "cmove")])
3910 (define_insn "*movhi_cc_reg_sp64"
3911 [(set (match_operand:HI 0 "register_operand" "=r,r")
3912 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
3913 [(match_operand:DI 2 "register_operand" "r,r")
3915 (match_operand:HI 3 "arith10_operand" "rM,0")
3916 (match_operand:HI 4 "arith10_operand" "0,rM")))]
3919 movr%D1\t%2, %r3, %0
3920 movr%d1\t%2, %r4, %0"
3921 [(set_attr "type" "cmove")])
3923 (define_insn "*movsi_cc_reg_sp64"
3924 [(set (match_operand:SI 0 "register_operand" "=r,r")
3925 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3926 [(match_operand:DI 2 "register_operand" "r,r")
3928 (match_operand:SI 3 "arith10_operand" "rM,0")
3929 (match_operand:SI 4 "arith10_operand" "0,rM")))]
3932 movr%D1\t%2, %r3, %0
3933 movr%d1\t%2, %r4, %0"
3934 [(set_attr "type" "cmove")])
3936 ;; ??? The constraints of operands 3,4 need work.
3937 (define_insn "*movdi_cc_reg_sp64"
3938 [(set (match_operand:DI 0 "register_operand" "=r,r")
3939 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
3940 [(match_operand:DI 2 "register_operand" "r,r")
3942 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
3943 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
3946 movr%D1\t%2, %r3, %0
3947 movr%d1\t%2, %r4, %0"
3948 [(set_attr "type" "cmove")])
3950 (define_insn "*movdi_cc_reg_sp64_trunc"
3951 [(set (match_operand:SI 0 "register_operand" "=r,r")
3952 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3953 [(match_operand:DI 2 "register_operand" "r,r")
3955 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
3956 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
3959 movr%D1\t%2, %r3, %0
3960 movr%d1\t%2, %r4, %0"
3961 [(set_attr "type" "cmove")])
3963 (define_insn "*movsf_cc_reg_sp64"
3964 [(set (match_operand:SF 0 "register_operand" "=f,f")
3965 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
3966 [(match_operand:DI 2 "register_operand" "r,r")
3968 (match_operand:SF 3 "register_operand" "f,0")
3969 (match_operand:SF 4 "register_operand" "0,f")))]
3970 "TARGET_ARCH64 && TARGET_FPU"
3972 fmovrs%D1\t%2, %3, %0
3973 fmovrs%d1\t%2, %4, %0"
3974 [(set_attr "type" "fpcrmove")])
3976 (define_insn "movdf_cc_reg_sp64"
3977 [(set (match_operand:DF 0 "register_operand" "=e,e")
3978 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
3979 [(match_operand:DI 2 "register_operand" "r,r")
3981 (match_operand:DF 3 "register_operand" "e,0")
3982 (match_operand:DF 4 "register_operand" "0,e")))]
3983 "TARGET_ARCH64 && TARGET_FPU"
3985 fmovrd%D1\t%2, %3, %0
3986 fmovrd%d1\t%2, %4, %0"
3987 [(set_attr "type" "fpcrmove")
3988 (set_attr "fptype" "double")])
3990 (define_insn "*movtf_cc_reg_hq_sp64"
3991 [(set (match_operand:TF 0 "register_operand" "=e,e")
3992 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
3993 [(match_operand:DI 2 "register_operand" "r,r")
3995 (match_operand:TF 3 "register_operand" "e,0")
3996 (match_operand:TF 4 "register_operand" "0,e")))]
3997 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3999 fmovrq%D1\t%2, %3, %0
4000 fmovrq%d1\t%2, %4, %0"
4001 [(set_attr "type" "fpcrmove")])
4003 (define_insn_and_split "*movtf_cc_reg_sp64"
4004 [(set (match_operand:TF 0 "register_operand" "=e,e")
4005 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4006 [(match_operand:DI 2 "register_operand" "r,r")
4008 (match_operand:TF 3 "register_operand" "e,0")
4009 (match_operand:TF 4 "register_operand" "0,e")))]
4010 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4012 "&& reload_completed"
4013 [(clobber (const_int 0))]
4015 rtx set_dest = operands[0];
4016 rtx set_srca = operands[3];
4017 rtx set_srcb = operands[4];
4018 int third = rtx_equal_p (set_dest, set_srca);
4020 rtx srca1, srca2, srcb1, srcb2;
4022 dest1 = gen_df_reg (set_dest, 0);
4023 dest2 = gen_df_reg (set_dest, 1);
4024 srca1 = gen_df_reg (set_srca, 0);
4025 srca2 = gen_df_reg (set_srca, 1);
4026 srcb1 = gen_df_reg (set_srcb, 0);
4027 srcb2 = gen_df_reg (set_srcb, 1);
4029 /* Now emit using the real source and destination we found, swapping
4030 the order if we detect overlap. */
4031 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4032 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4034 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4035 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4039 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4040 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4044 [(set_attr "length" "2")])
4047 ;;- zero extension instructions
4049 ;; These patterns originally accepted general_operands, however, slightly
4050 ;; better code is generated by only accepting register_operands, and then
4051 ;; letting combine generate the ldu[hb] insns.
4053 (define_expand "zero_extendhisi2"
4054 [(set (match_operand:SI 0 "register_operand" "")
4055 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4058 rtx temp = gen_reg_rtx (SImode);
4059 rtx shift_16 = GEN_INT (16);
4060 int op1_subbyte = 0;
4062 if (GET_CODE (operand1) == SUBREG)
4064 op1_subbyte = SUBREG_BYTE (operand1);
4065 op1_subbyte /= GET_MODE_SIZE (SImode);
4066 op1_subbyte *= GET_MODE_SIZE (SImode);
4067 operand1 = XEXP (operand1, 0);
4070 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4072 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4076 (define_insn "*zero_extendhisi2_insn"
4077 [(set (match_operand:SI 0 "register_operand" "=r")
4078 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4081 [(set_attr "type" "load")
4082 (set_attr "us3load_type" "3cycle")])
4084 (define_expand "zero_extendqihi2"
4085 [(set (match_operand:HI 0 "register_operand" "")
4086 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4090 (define_insn "*zero_extendqihi2_insn"
4091 [(set (match_operand:HI 0 "register_operand" "=r,r")
4092 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4093 "GET_CODE (operands[1]) != CONST_INT"
4097 [(set_attr "type" "*,load")
4098 (set_attr "us3load_type" "*,3cycle")])
4100 (define_expand "zero_extendqisi2"
4101 [(set (match_operand:SI 0 "register_operand" "")
4102 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4106 (define_insn "*zero_extendqisi2_insn"
4107 [(set (match_operand:SI 0 "register_operand" "=r,r")
4108 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4109 "GET_CODE (operands[1]) != CONST_INT"
4113 [(set_attr "type" "*,load")
4114 (set_attr "us3load_type" "*,3cycle")])
4116 (define_expand "zero_extendqidi2"
4117 [(set (match_operand:DI 0 "register_operand" "")
4118 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4122 (define_insn "*zero_extendqidi2_insn"
4123 [(set (match_operand:DI 0 "register_operand" "=r,r")
4124 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4125 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4129 [(set_attr "type" "*,load")
4130 (set_attr "us3load_type" "*,3cycle")])
4132 (define_expand "zero_extendhidi2"
4133 [(set (match_operand:DI 0 "register_operand" "")
4134 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4137 rtx temp = gen_reg_rtx (DImode);
4138 rtx shift_48 = GEN_INT (48);
4139 int op1_subbyte = 0;
4141 if (GET_CODE (operand1) == SUBREG)
4143 op1_subbyte = SUBREG_BYTE (operand1);
4144 op1_subbyte /= GET_MODE_SIZE (DImode);
4145 op1_subbyte *= GET_MODE_SIZE (DImode);
4146 operand1 = XEXP (operand1, 0);
4149 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4151 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4155 (define_insn "*zero_extendhidi2_insn"
4156 [(set (match_operand:DI 0 "register_operand" "=r")
4157 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4160 [(set_attr "type" "load")
4161 (set_attr "us3load_type" "3cycle")])
4164 ;; ??? Write truncdisi pattern using sra?
4166 (define_expand "zero_extendsidi2"
4167 [(set (match_operand:DI 0 "register_operand" "")
4168 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4172 (define_insn "*zero_extendsidi2_insn_sp64"
4173 [(set (match_operand:DI 0 "register_operand" "=r,r")
4174 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4175 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4179 [(set_attr "type" "shift,load")])
4181 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
4182 [(set (match_operand:DI 0 "register_operand" "=r")
4183 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4186 "&& reload_completed"
4187 [(set (match_dup 2) (match_dup 3))
4188 (set (match_dup 4) (match_dup 5))]
4192 dest1 = gen_highpart (SImode, operands[0]);
4193 dest2 = gen_lowpart (SImode, operands[0]);
4195 /* Swap the order in case of overlap. */
4196 if (REGNO (dest1) == REGNO (operands[1]))
4198 operands[2] = dest2;
4199 operands[3] = operands[1];
4200 operands[4] = dest1;
4201 operands[5] = const0_rtx;
4205 operands[2] = dest1;
4206 operands[3] = const0_rtx;
4207 operands[4] = dest2;
4208 operands[5] = operands[1];
4211 [(set_attr "length" "2")])
4213 ;; Simplify comparisons of extended values.
4215 (define_insn "*cmp_zero_extendqisi2"
4217 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4220 "andcc\t%0, 0xff, %%g0"
4221 [(set_attr "type" "compare")])
4223 (define_insn "*cmp_zero_qi"
4225 (compare:CC (match_operand:QI 0 "register_operand" "r")
4228 "andcc\t%0, 0xff, %%g0"
4229 [(set_attr "type" "compare")])
4231 (define_insn "*cmp_zero_extendqisi2_set"
4233 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4235 (set (match_operand:SI 0 "register_operand" "=r")
4236 (zero_extend:SI (match_dup 1)))]
4238 "andcc\t%1, 0xff, %0"
4239 [(set_attr "type" "compare")])
4241 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4243 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4246 (set (match_operand:SI 0 "register_operand" "=r")
4247 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4249 "andcc\t%1, 0xff, %0"
4250 [(set_attr "type" "compare")])
4252 (define_insn "*cmp_zero_extendqidi2"
4254 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4257 "andcc\t%0, 0xff, %%g0"
4258 [(set_attr "type" "compare")])
4260 (define_insn "*cmp_zero_qi_sp64"
4262 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4265 "andcc\t%0, 0xff, %%g0"
4266 [(set_attr "type" "compare")])
4268 (define_insn "*cmp_zero_extendqidi2_set"
4270 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4272 (set (match_operand:DI 0 "register_operand" "=r")
4273 (zero_extend:DI (match_dup 1)))]
4275 "andcc\t%1, 0xff, %0"
4276 [(set_attr "type" "compare")])
4278 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4280 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4283 (set (match_operand:DI 0 "register_operand" "=r")
4284 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4286 "andcc\t%1, 0xff, %0"
4287 [(set_attr "type" "compare")])
4289 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4291 (define_insn "*cmp_siqi_trunc"
4293 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4296 "andcc\t%0, 0xff, %%g0"
4297 [(set_attr "type" "compare")])
4299 (define_insn "*cmp_siqi_trunc_set"
4301 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4303 (set (match_operand:QI 0 "register_operand" "=r")
4304 (subreg:QI (match_dup 1) 3))]
4306 "andcc\t%1, 0xff, %0"
4307 [(set_attr "type" "compare")])
4309 (define_insn "*cmp_diqi_trunc"
4311 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4314 "andcc\t%0, 0xff, %%g0"
4315 [(set_attr "type" "compare")])
4317 (define_insn "*cmp_diqi_trunc_set"
4319 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4321 (set (match_operand:QI 0 "register_operand" "=r")
4322 (subreg:QI (match_dup 1) 7))]
4324 "andcc\t%1, 0xff, %0"
4325 [(set_attr "type" "compare")])
4327 ;;- sign extension instructions
4329 ;; These patterns originally accepted general_operands, however, slightly
4330 ;; better code is generated by only accepting register_operands, and then
4331 ;; letting combine generate the lds[hb] insns.
4333 (define_expand "extendhisi2"
4334 [(set (match_operand:SI 0 "register_operand" "")
4335 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4338 rtx temp = gen_reg_rtx (SImode);
4339 rtx shift_16 = GEN_INT (16);
4340 int op1_subbyte = 0;
4342 if (GET_CODE (operand1) == SUBREG)
4344 op1_subbyte = SUBREG_BYTE (operand1);
4345 op1_subbyte /= GET_MODE_SIZE (SImode);
4346 op1_subbyte *= GET_MODE_SIZE (SImode);
4347 operand1 = XEXP (operand1, 0);
4350 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4352 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4356 (define_insn "*sign_extendhisi2_insn"
4357 [(set (match_operand:SI 0 "register_operand" "=r")
4358 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4361 [(set_attr "type" "sload")
4362 (set_attr "us3load_type" "3cycle")])
4364 (define_expand "extendqihi2"
4365 [(set (match_operand:HI 0 "register_operand" "")
4366 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4369 rtx temp = gen_reg_rtx (SImode);
4370 rtx shift_24 = GEN_INT (24);
4371 int op1_subbyte = 0;
4372 int op0_subbyte = 0;
4374 if (GET_CODE (operand1) == SUBREG)
4376 op1_subbyte = SUBREG_BYTE (operand1);
4377 op1_subbyte /= GET_MODE_SIZE (SImode);
4378 op1_subbyte *= GET_MODE_SIZE (SImode);
4379 operand1 = XEXP (operand1, 0);
4381 if (GET_CODE (operand0) == SUBREG)
4383 op0_subbyte = SUBREG_BYTE (operand0);
4384 op0_subbyte /= GET_MODE_SIZE (SImode);
4385 op0_subbyte *= GET_MODE_SIZE (SImode);
4386 operand0 = XEXP (operand0, 0);
4388 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4390 if (GET_MODE (operand0) != SImode)
4391 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4392 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4396 (define_insn "*sign_extendqihi2_insn"
4397 [(set (match_operand:HI 0 "register_operand" "=r")
4398 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4401 [(set_attr "type" "sload")
4402 (set_attr "us3load_type" "3cycle")])
4404 (define_expand "extendqisi2"
4405 [(set (match_operand:SI 0 "register_operand" "")
4406 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4409 rtx temp = gen_reg_rtx (SImode);
4410 rtx shift_24 = GEN_INT (24);
4411 int op1_subbyte = 0;
4413 if (GET_CODE (operand1) == SUBREG)
4415 op1_subbyte = SUBREG_BYTE (operand1);
4416 op1_subbyte /= GET_MODE_SIZE (SImode);
4417 op1_subbyte *= GET_MODE_SIZE (SImode);
4418 operand1 = XEXP (operand1, 0);
4421 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4423 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4427 (define_insn "*sign_extendqisi2_insn"
4428 [(set (match_operand:SI 0 "register_operand" "=r")
4429 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4432 [(set_attr "type" "sload")
4433 (set_attr "us3load_type" "3cycle")])
4435 (define_expand "extendqidi2"
4436 [(set (match_operand:DI 0 "register_operand" "")
4437 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4440 rtx temp = gen_reg_rtx (DImode);
4441 rtx shift_56 = GEN_INT (56);
4442 int op1_subbyte = 0;
4444 if (GET_CODE (operand1) == SUBREG)
4446 op1_subbyte = SUBREG_BYTE (operand1);
4447 op1_subbyte /= GET_MODE_SIZE (DImode);
4448 op1_subbyte *= GET_MODE_SIZE (DImode);
4449 operand1 = XEXP (operand1, 0);
4452 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4454 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4458 (define_insn "*sign_extendqidi2_insn"
4459 [(set (match_operand:DI 0 "register_operand" "=r")
4460 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4463 [(set_attr "type" "sload")
4464 (set_attr "us3load_type" "3cycle")])
4466 (define_expand "extendhidi2"
4467 [(set (match_operand:DI 0 "register_operand" "")
4468 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4471 rtx temp = gen_reg_rtx (DImode);
4472 rtx shift_48 = GEN_INT (48);
4473 int op1_subbyte = 0;
4475 if (GET_CODE (operand1) == SUBREG)
4477 op1_subbyte = SUBREG_BYTE (operand1);
4478 op1_subbyte /= GET_MODE_SIZE (DImode);
4479 op1_subbyte *= GET_MODE_SIZE (DImode);
4480 operand1 = XEXP (operand1, 0);
4483 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4485 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4489 (define_insn "*sign_extendhidi2_insn"
4490 [(set (match_operand:DI 0 "register_operand" "=r")
4491 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4494 [(set_attr "type" "sload")
4495 (set_attr "us3load_type" "3cycle")])
4497 (define_expand "extendsidi2"
4498 [(set (match_operand:DI 0 "register_operand" "")
4499 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4503 (define_insn "*sign_extendsidi2_insn"
4504 [(set (match_operand:DI 0 "register_operand" "=r,r")
4505 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4510 [(set_attr "type" "shift,sload")
4511 (set_attr "us3load_type" "*,3cycle")])
4513 ;; Special pattern for optimizing bit-field compares. This is needed
4514 ;; because combine uses this as a canonical form.
4516 (define_insn "*cmp_zero_extract"
4519 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4520 (match_operand:SI 1 "small_int_or_double" "n")
4521 (match_operand:SI 2 "small_int_or_double" "n"))
4523 "(GET_CODE (operands[2]) == CONST_INT
4524 && INTVAL (operands[2]) > 19)
4525 || (GET_CODE (operands[2]) == CONST_DOUBLE
4526 && CONST_DOUBLE_LOW (operands[2]) > 19)"
4528 int len = (GET_CODE (operands[1]) == CONST_INT
4529 ? INTVAL (operands[1])
4530 : CONST_DOUBLE_LOW (operands[1]));
4532 (GET_CODE (operands[2]) == CONST_INT
4533 ? INTVAL (operands[2])
4534 : CONST_DOUBLE_LOW (operands[2])) - len;
4535 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4537 operands[1] = GEN_INT (mask);
4538 return "andcc\t%0, %1, %%g0";
4540 [(set_attr "type" "compare")])
4542 (define_insn "*cmp_zero_extract_sp64"
4545 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4546 (match_operand:SI 1 "small_int_or_double" "n")
4547 (match_operand:SI 2 "small_int_or_double" "n"))
4550 && ((GET_CODE (operands[2]) == CONST_INT
4551 && INTVAL (operands[2]) > 51)
4552 || (GET_CODE (operands[2]) == CONST_DOUBLE
4553 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4555 int len = (GET_CODE (operands[1]) == CONST_INT
4556 ? INTVAL (operands[1])
4557 : CONST_DOUBLE_LOW (operands[1]));
4559 (GET_CODE (operands[2]) == CONST_INT
4560 ? INTVAL (operands[2])
4561 : CONST_DOUBLE_LOW (operands[2])) - len;
4562 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4564 operands[1] = GEN_INT (mask);
4565 return "andcc\t%0, %1, %%g0";
4567 [(set_attr "type" "compare")])
4569 ;; Conversions between float, double and long double.
4571 (define_insn "extendsfdf2"
4572 [(set (match_operand:DF 0 "register_operand" "=e")
4574 (match_operand:SF 1 "register_operand" "f")))]
4577 [(set_attr "type" "fp")
4578 (set_attr "fptype" "double")])
4580 (define_expand "extendsftf2"
4581 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4583 (match_operand:SF 1 "register_operand" "")))]
4584 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4585 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4587 (define_insn "*extendsftf2_hq"
4588 [(set (match_operand:TF 0 "register_operand" "=e")
4590 (match_operand:SF 1 "register_operand" "f")))]
4591 "TARGET_FPU && TARGET_HARD_QUAD"
4593 [(set_attr "type" "fp")])
4595 (define_expand "extenddftf2"
4596 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4598 (match_operand:DF 1 "register_operand" "")))]
4599 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4600 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4602 (define_insn "*extenddftf2_hq"
4603 [(set (match_operand:TF 0 "register_operand" "=e")
4605 (match_operand:DF 1 "register_operand" "e")))]
4606 "TARGET_FPU && TARGET_HARD_QUAD"
4608 [(set_attr "type" "fp")])
4610 (define_insn "truncdfsf2"
4611 [(set (match_operand:SF 0 "register_operand" "=f")
4613 (match_operand:DF 1 "register_operand" "e")))]
4616 [(set_attr "type" "fp")
4617 (set_attr "fptype" "double")])
4619 (define_expand "trunctfsf2"
4620 [(set (match_operand:SF 0 "register_operand" "")
4622 (match_operand:TF 1 "general_operand" "")))]
4623 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4624 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4626 (define_insn "*trunctfsf2_hq"
4627 [(set (match_operand:SF 0 "register_operand" "=f")
4629 (match_operand:TF 1 "register_operand" "e")))]
4630 "TARGET_FPU && TARGET_HARD_QUAD"
4632 [(set_attr "type" "fp")])
4634 (define_expand "trunctfdf2"
4635 [(set (match_operand:DF 0 "register_operand" "")
4637 (match_operand:TF 1 "general_operand" "")))]
4638 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4639 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4641 (define_insn "*trunctfdf2_hq"
4642 [(set (match_operand:DF 0 "register_operand" "=e")
4644 (match_operand:TF 1 "register_operand" "e")))]
4645 "TARGET_FPU && TARGET_HARD_QUAD"
4647 [(set_attr "type" "fp")])
4649 ;; Conversion between fixed point and floating point.
4651 (define_insn "floatsisf2"
4652 [(set (match_operand:SF 0 "register_operand" "=f")
4653 (float:SF (match_operand:SI 1 "register_operand" "f")))]
4656 [(set_attr "type" "fp")
4657 (set_attr "fptype" "double")])
4659 (define_insn "floatsidf2"
4660 [(set (match_operand:DF 0 "register_operand" "=e")
4661 (float:DF (match_operand:SI 1 "register_operand" "f")))]
4664 [(set_attr "type" "fp")
4665 (set_attr "fptype" "double")])
4667 (define_expand "floatsitf2"
4668 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4669 (float:TF (match_operand:SI 1 "register_operand" "")))]
4670 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4671 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4673 (define_insn "*floatsitf2_hq"
4674 [(set (match_operand:TF 0 "register_operand" "=e")
4675 (float:TF (match_operand:SI 1 "register_operand" "f")))]
4676 "TARGET_FPU && TARGET_HARD_QUAD"
4678 [(set_attr "type" "fp")])
4680 (define_expand "floatunssitf2"
4681 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4682 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
4683 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4684 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4686 ;; Now the same for 64 bit sources.
4688 (define_insn "floatdisf2"
4689 [(set (match_operand:SF 0 "register_operand" "=f")
4690 (float:SF (match_operand:DI 1 "register_operand" "e")))]
4691 "TARGET_V9 && TARGET_FPU"
4693 [(set_attr "type" "fp")
4694 (set_attr "fptype" "double")])
4696 (define_expand "floatunsdisf2"
4697 [(use (match_operand:SF 0 "register_operand" ""))
4698 (use (match_operand:DI 1 "general_operand" ""))]
4699 "TARGET_ARCH64 && TARGET_FPU"
4700 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
4702 (define_insn "floatdidf2"
4703 [(set (match_operand:DF 0 "register_operand" "=e")
4704 (float:DF (match_operand:DI 1 "register_operand" "e")))]
4705 "TARGET_V9 && TARGET_FPU"
4707 [(set_attr "type" "fp")
4708 (set_attr "fptype" "double")])
4710 (define_expand "floatunsdidf2"
4711 [(use (match_operand:DF 0 "register_operand" ""))
4712 (use (match_operand:DI 1 "general_operand" ""))]
4713 "TARGET_ARCH64 && TARGET_FPU"
4714 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
4716 (define_expand "floatditf2"
4717 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4718 (float:TF (match_operand:DI 1 "register_operand" "")))]
4719 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4720 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4722 (define_insn "*floatditf2_hq"
4723 [(set (match_operand:TF 0 "register_operand" "=e")
4724 (float:TF (match_operand:DI 1 "register_operand" "e")))]
4725 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4727 [(set_attr "type" "fp")])
4729 (define_expand "floatunsditf2"
4730 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4731 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
4732 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4733 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4735 ;; Convert a float to an actual integer.
4736 ;; Truncation is performed as part of the conversion.
4738 (define_insn "fix_truncsfsi2"
4739 [(set (match_operand:SI 0 "register_operand" "=f")
4740 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4743 [(set_attr "type" "fp")
4744 (set_attr "fptype" "double")])
4746 (define_insn "fix_truncdfsi2"
4747 [(set (match_operand:SI 0 "register_operand" "=f")
4748 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4751 [(set_attr "type" "fp")
4752 (set_attr "fptype" "double")])
4754 (define_expand "fix_trunctfsi2"
4755 [(set (match_operand:SI 0 "register_operand" "")
4756 (fix:SI (match_operand:TF 1 "general_operand" "")))]
4757 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4758 "emit_tfmode_cvt (FIX, operands); DONE;")
4760 (define_insn "*fix_trunctfsi2_hq"
4761 [(set (match_operand:SI 0 "register_operand" "=f")
4762 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4763 "TARGET_FPU && TARGET_HARD_QUAD"
4765 [(set_attr "type" "fp")])
4767 (define_expand "fixuns_trunctfsi2"
4768 [(set (match_operand:SI 0 "register_operand" "")
4769 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4770 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4771 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4773 ;; Now the same, for V9 targets
4775 (define_insn "fix_truncsfdi2"
4776 [(set (match_operand:DI 0 "register_operand" "=e")
4777 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4778 "TARGET_V9 && TARGET_FPU"
4780 [(set_attr "type" "fp")
4781 (set_attr "fptype" "double")])
4783 (define_expand "fixuns_truncsfdi2"
4784 [(use (match_operand:DI 0 "register_operand" ""))
4785 (use (match_operand:SF 1 "general_operand" ""))]
4786 "TARGET_ARCH64 && TARGET_FPU"
4787 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
4789 (define_insn "fix_truncdfdi2"
4790 [(set (match_operand:DI 0 "register_operand" "=e")
4791 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4792 "TARGET_V9 && TARGET_FPU"
4794 [(set_attr "type" "fp")
4795 (set_attr "fptype" "double")])
4797 (define_expand "fixuns_truncdfdi2"
4798 [(use (match_operand:DI 0 "register_operand" ""))
4799 (use (match_operand:DF 1 "general_operand" ""))]
4800 "TARGET_ARCH64 && TARGET_FPU"
4801 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
4803 (define_expand "fix_trunctfdi2"
4804 [(set (match_operand:DI 0 "register_operand" "")
4805 (fix:DI (match_operand:TF 1 "general_operand" "")))]
4806 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4807 "emit_tfmode_cvt (FIX, operands); DONE;")
4809 (define_insn "*fix_trunctfdi2_hq"
4810 [(set (match_operand:DI 0 "register_operand" "=e")
4811 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4812 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4814 [(set_attr "type" "fp")])
4816 (define_expand "fixuns_trunctfdi2"
4817 [(set (match_operand:DI 0 "register_operand" "")
4818 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4819 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4820 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4822 ;;- arithmetic instructions
4824 (define_expand "adddi3"
4825 [(set (match_operand:DI 0 "register_operand" "")
4826 (plus:DI (match_operand:DI 1 "register_operand" "")
4827 (match_operand:DI 2 "arith_double_add_operand" "")))]
4830 if (! TARGET_ARCH64)
4832 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4833 gen_rtx_SET (VOIDmode, operands[0],
4834 gen_rtx_PLUS (DImode, operands[1],
4836 gen_rtx_CLOBBER (VOIDmode,
4837 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4842 (define_insn_and_split "adddi3_insn_sp32"
4843 [(set (match_operand:DI 0 "register_operand" "=r")
4844 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4845 (match_operand:DI 2 "arith_double_operand" "rHI")))
4846 (clobber (reg:CC 100))]
4849 "&& reload_completed"
4850 [(parallel [(set (reg:CC_NOOV 100)
4851 (compare:CC_NOOV (plus:SI (match_dup 4)
4855 (plus:SI (match_dup 4) (match_dup 5)))])
4857 (plus:SI (plus:SI (match_dup 7)
4859 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4861 operands[3] = gen_lowpart (SImode, operands[0]);
4862 operands[4] = gen_lowpart (SImode, operands[1]);
4863 operands[5] = gen_lowpart (SImode, operands[2]);
4864 operands[6] = gen_highpart (SImode, operands[0]);
4865 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4866 #if HOST_BITS_PER_WIDE_INT == 32
4867 if (GET_CODE (operands[2]) == CONST_INT)
4869 if (INTVAL (operands[2]) < 0)
4870 operands[8] = constm1_rtx;
4872 operands[8] = const0_rtx;
4876 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4878 [(set_attr "length" "2")])
4881 [(set (match_operand:DI 0 "register_operand" "")
4882 (minus:DI (match_operand:DI 1 "arith_double_operand" "")
4883 (match_operand:DI 2 "arith_double_operand" "")))
4884 (clobber (reg:CC 100))]
4885 "! TARGET_ARCH64 && reload_completed"
4886 [(parallel [(set (reg:CC_NOOV 100)
4887 (compare:CC_NOOV (minus:SI (match_dup 4)
4891 (minus:SI (match_dup 4) (match_dup 5)))])
4893 (minus:SI (minus:SI (match_dup 7)
4895 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4897 operands[3] = gen_lowpart (SImode, operands[0]);
4898 operands[4] = gen_lowpart (SImode, operands[1]);
4899 operands[5] = gen_lowpart (SImode, operands[2]);
4900 operands[6] = gen_highpart (SImode, operands[0]);
4901 operands[7] = gen_highpart (SImode, operands[1]);
4902 #if HOST_BITS_PER_WIDE_INT == 32
4903 if (GET_CODE (operands[2]) == CONST_INT)
4905 if (INTVAL (operands[2]) < 0)
4906 operands[8] = constm1_rtx;
4908 operands[8] = const0_rtx;
4912 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4915 ;; LTU here means "carry set"
4917 [(set (match_operand:SI 0 "register_operand" "=r")
4918 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4919 (match_operand:SI 2 "arith_operand" "rI"))
4920 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4923 [(set_attr "type" "ialuX")])
4925 (define_insn_and_split "*addx_extend_sp32"
4926 [(set (match_operand:DI 0 "register_operand" "=r")
4927 (zero_extend:DI (plus:SI (plus:SI
4928 (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4929 (match_operand:SI 2 "arith_operand" "rI"))
4930 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4933 "&& reload_completed"
4934 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4935 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4936 (set (match_dup 4) (const_int 0))]
4937 "operands[3] = gen_lowpart (SImode, operands[0]);
4938 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4939 [(set_attr "length" "2")])
4941 (define_insn "*addx_extend_sp64"
4942 [(set (match_operand:DI 0 "register_operand" "=r")
4943 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4944 (match_operand:SI 2 "arith_operand" "rI"))
4945 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4948 [(set_attr "type" "ialuX")])
4951 [(set (match_operand:SI 0 "register_operand" "=r")
4952 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4953 (match_operand:SI 2 "arith_operand" "rI"))
4954 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4957 [(set_attr "type" "ialuX")])
4959 (define_insn "*subx_extend_sp64"
4960 [(set (match_operand:DI 0 "register_operand" "=r")
4961 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4962 (match_operand:SI 2 "arith_operand" "rI"))
4963 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4966 [(set_attr "type" "ialuX")])
4968 (define_insn_and_split "*subx_extend"
4969 [(set (match_operand:DI 0 "register_operand" "=r")
4970 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4971 (match_operand:SI 2 "arith_operand" "rI"))
4972 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4975 "&& reload_completed"
4976 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4977 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4978 (set (match_dup 4) (const_int 0))]
4979 "operands[3] = gen_lowpart (SImode, operands[0]);
4980 operands[4] = gen_highpart (SImode, operands[0]);"
4981 [(set_attr "length" "2")])
4983 (define_insn_and_split ""
4984 [(set (match_operand:DI 0 "register_operand" "=r")
4985 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4986 (match_operand:DI 2 "register_operand" "r")))
4987 (clobber (reg:CC 100))]
4990 "&& reload_completed"
4991 [(parallel [(set (reg:CC_NOOV 100)
4992 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
4994 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
4996 (plus:SI (plus:SI (match_dup 4) (const_int 0))
4997 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4998 "operands[3] = gen_lowpart (SImode, operands[2]);
4999 operands[4] = gen_highpart (SImode, operands[2]);
5000 operands[5] = gen_lowpart (SImode, operands[0]);
5001 operands[6] = gen_highpart (SImode, operands[0]);"
5002 [(set_attr "length" "2")])
5004 (define_insn "*adddi3_sp64"
5005 [(set (match_operand:DI 0 "register_operand" "=r,r")
5006 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
5007 (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
5013 (define_insn "addsi3"
5014 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
5015 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
5016 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
5021 fpadd32s\t%1, %2, %0"
5022 [(set_attr "type" "*,*,fga")])
5024 (define_insn "*cmp_cc_plus"
5025 [(set (reg:CC_NOOV 100)
5026 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5027 (match_operand:SI 1 "arith_operand" "rI"))
5030 "addcc\t%0, %1, %%g0"
5031 [(set_attr "type" "compare")])
5033 (define_insn "*cmp_ccx_plus"
5034 [(set (reg:CCX_NOOV 100)
5035 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5036 (match_operand:DI 1 "arith_double_operand" "rHI"))
5039 "addcc\t%0, %1, %%g0"
5040 [(set_attr "type" "compare")])
5042 (define_insn "*cmp_cc_plus_set"
5043 [(set (reg:CC_NOOV 100)
5044 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5045 (match_operand:SI 2 "arith_operand" "rI"))
5047 (set (match_operand:SI 0 "register_operand" "=r")
5048 (plus:SI (match_dup 1) (match_dup 2)))]
5051 [(set_attr "type" "compare")])
5053 (define_insn "*cmp_ccx_plus_set"
5054 [(set (reg:CCX_NOOV 100)
5055 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5056 (match_operand:DI 2 "arith_double_operand" "rHI"))
5058 (set (match_operand:DI 0 "register_operand" "=r")
5059 (plus:DI (match_dup 1) (match_dup 2)))]
5062 [(set_attr "type" "compare")])
5064 (define_expand "subdi3"
5065 [(set (match_operand:DI 0 "register_operand" "")
5066 (minus:DI (match_operand:DI 1 "register_operand" "")
5067 (match_operand:DI 2 "arith_double_add_operand" "")))]
5070 if (! TARGET_ARCH64)
5072 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5073 gen_rtx_SET (VOIDmode, operands[0],
5074 gen_rtx_MINUS (DImode, operands[1],
5076 gen_rtx_CLOBBER (VOIDmode,
5077 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5082 (define_insn_and_split "*subdi3_sp32"
5083 [(set (match_operand:DI 0 "register_operand" "=r")
5084 (minus:DI (match_operand:DI 1 "register_operand" "r")
5085 (match_operand:DI 2 "arith_double_operand" "rHI")))
5086 (clobber (reg:CC 100))]
5089 "&& reload_completed
5090 && (GET_CODE (operands[2]) == CONST_INT
5091 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5092 [(clobber (const_int 0))]
5096 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5097 lowp = gen_lowpart (SImode, operands[2]);
5098 if ((lowp == const0_rtx)
5099 && (operands[0] == operands[1]))
5101 emit_insn (gen_rtx_SET (VOIDmode,
5102 gen_highpart (SImode, operands[0]),
5103 gen_rtx_MINUS (SImode,
5104 gen_highpart_mode (SImode, DImode,
5110 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5111 gen_lowpart (SImode, operands[1]),
5113 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5114 gen_highpart_mode (SImode, DImode, operands[1]),
5119 [(set_attr "length" "2")])
5122 [(set (match_operand:DI 0 "register_operand" "")
5123 (minus:DI (match_operand:DI 1 "register_operand" "")
5124 (match_operand:DI 2 "register_operand" "")))
5125 (clobber (reg:CC 100))]
5127 && reload_completed"
5128 [(clobber (const_int 0))]
5130 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5131 gen_lowpart (SImode, operands[1]),
5132 gen_lowpart (SImode, operands[2])));
5133 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5134 gen_highpart (SImode, operands[1]),
5135 gen_highpart (SImode, operands[2])));
5139 (define_insn_and_split ""
5140 [(set (match_operand:DI 0 "register_operand" "=r")
5141 (minus:DI (match_operand:DI 1 "register_operand" "r")
5142 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5143 (clobber (reg:CC 100))]
5146 "&& reload_completed"
5147 [(parallel [(set (reg:CC_NOOV 100)
5148 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5150 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5152 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5153 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5154 "operands[3] = gen_lowpart (SImode, operands[1]);
5155 operands[4] = gen_highpart (SImode, operands[1]);
5156 operands[5] = gen_lowpart (SImode, operands[0]);
5157 operands[6] = gen_highpart (SImode, operands[0]);"
5158 [(set_attr "length" "2")])
5160 (define_insn "*subdi3_sp64"
5161 [(set (match_operand:DI 0 "register_operand" "=r,r")
5162 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
5163 (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
5169 (define_insn "subsi3"
5170 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
5171 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
5172 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
5177 fpsub32s\t%1, %2, %0"
5178 [(set_attr "type" "*,*,fga")])
5180 (define_insn "*cmp_minus_cc"
5181 [(set (reg:CC_NOOV 100)
5182 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5183 (match_operand:SI 1 "arith_operand" "rI"))
5186 "subcc\t%r0, %1, %%g0"
5187 [(set_attr "type" "compare")])
5189 (define_insn "*cmp_minus_ccx"
5190 [(set (reg:CCX_NOOV 100)
5191 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5192 (match_operand:DI 1 "arith_double_operand" "rHI"))
5195 "subcc\t%0, %1, %%g0"
5196 [(set_attr "type" "compare")])
5198 (define_insn "cmp_minus_cc_set"
5199 [(set (reg:CC_NOOV 100)
5200 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5201 (match_operand:SI 2 "arith_operand" "rI"))
5203 (set (match_operand:SI 0 "register_operand" "=r")
5204 (minus:SI (match_dup 1) (match_dup 2)))]
5206 "subcc\t%r1, %2, %0"
5207 [(set_attr "type" "compare")])
5209 (define_insn "*cmp_minus_ccx_set"
5210 [(set (reg:CCX_NOOV 100)
5211 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5212 (match_operand:DI 2 "arith_double_operand" "rHI"))
5214 (set (match_operand:DI 0 "register_operand" "=r")
5215 (minus:DI (match_dup 1) (match_dup 2)))]
5218 [(set_attr "type" "compare")])
5220 ;; Integer Multiply/Divide.
5222 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5223 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5225 (define_insn "mulsi3"
5226 [(set (match_operand:SI 0 "register_operand" "=r")
5227 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5228 (match_operand:SI 2 "arith_operand" "rI")))]
5231 [(set_attr "type" "imul")])
5233 (define_expand "muldi3"
5234 [(set (match_operand:DI 0 "register_operand" "=r")
5235 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5236 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5237 "TARGET_ARCH64 || TARGET_V8PLUS"
5241 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5246 (define_insn "*muldi3_sp64"
5247 [(set (match_operand:DI 0 "register_operand" "=r")
5248 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5249 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5252 [(set_attr "type" "imul")])
5254 ;; V8plus wide multiply.
5256 (define_insn "muldi3_v8plus"
5257 [(set (match_operand:DI 0 "register_operand" "=r,h")
5258 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5259 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5260 (clobber (match_scratch:SI 3 "=&h,X"))
5261 (clobber (match_scratch:SI 4 "=&h,X"))]
5264 if (sparc_check_64 (operands[1], insn) <= 0)
5265 output_asm_insn ("srl\t%L1, 0, %L1", operands);
5266 if (which_alternative == 1)
5267 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
5268 if (GET_CODE (operands[2]) == CONST_INT)
5270 if (which_alternative == 1)
5271 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
5273 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";
5275 else if (rtx_equal_p (operands[1], operands[2]))
5277 if (which_alternative == 1)
5278 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
5280 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";
5282 if (sparc_check_64 (operands[2], insn) <= 0)
5283 output_asm_insn ("srl\t%L2, 0, %L2", operands);
5284 if (which_alternative == 1)
5285 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";
5287 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";
5289 [(set_attr "type" "multi")
5290 (set_attr "length" "9,8")])
5292 (define_insn "*cmp_mul_set"
5294 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5295 (match_operand:SI 2 "arith_operand" "rI"))
5297 (set (match_operand:SI 0 "register_operand" "=r")
5298 (mult:SI (match_dup 1) (match_dup 2)))]
5299 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5300 "smulcc\t%1, %2, %0"
5301 [(set_attr "type" "imul")])
5303 (define_expand "mulsidi3"
5304 [(set (match_operand:DI 0 "register_operand" "")
5305 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5306 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5309 if (CONSTANT_P (operands[2]))
5312 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5314 else if (TARGET_ARCH32)
5315 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5318 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
5324 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5329 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5330 ;; registers can hold 64 bit values in the V8plus environment.
5332 (define_insn "mulsidi3_v8plus"
5333 [(set (match_operand:DI 0 "register_operand" "=h,r")
5334 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5335 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5336 (clobber (match_scratch:SI 3 "=X,&h"))]
5339 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5340 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5341 [(set_attr "type" "multi")
5342 (set_attr "length" "2,3")])
5345 (define_insn "const_mulsidi3_v8plus"
5346 [(set (match_operand:DI 0 "register_operand" "=h,r")
5347 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5348 (match_operand:DI 2 "small_int" "I,I")))
5349 (clobber (match_scratch:SI 3 "=X,&h"))]
5352 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5353 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5354 [(set_attr "type" "multi")
5355 (set_attr "length" "2,3")])
5358 (define_insn "*mulsidi3_sp32"
5359 [(set (match_operand:DI 0 "register_operand" "=r")
5360 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5361 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5364 return TARGET_SPARCLET
5365 ? "smuld\t%1, %2, %L0"
5366 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5369 (if_then_else (eq_attr "isa" "sparclet")
5370 (const_string "imul") (const_string "multi")))
5371 (set (attr "length")
5372 (if_then_else (eq_attr "isa" "sparclet")
5373 (const_int 1) (const_int 2)))])
5375 (define_insn "*mulsidi3_sp64"
5376 [(set (match_operand:DI 0 "register_operand" "=r")
5377 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5378 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5379 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5381 [(set_attr "type" "imul")])
5383 ;; Extra pattern, because sign_extend of a constant isn't valid.
5386 (define_insn "const_mulsidi3_sp32"
5387 [(set (match_operand:DI 0 "register_operand" "=r")
5388 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5389 (match_operand:DI 2 "small_int" "I")))]
5392 return TARGET_SPARCLET
5393 ? "smuld\t%1, %2, %L0"
5394 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5397 (if_then_else (eq_attr "isa" "sparclet")
5398 (const_string "imul") (const_string "multi")))
5399 (set (attr "length")
5400 (if_then_else (eq_attr "isa" "sparclet")
5401 (const_int 1) (const_int 2)))])
5403 (define_insn "const_mulsidi3_sp64"
5404 [(set (match_operand:DI 0 "register_operand" "=r")
5405 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5406 (match_operand:DI 2 "small_int" "I")))]
5407 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5409 [(set_attr "type" "imul")])
5411 (define_expand "smulsi3_highpart"
5412 [(set (match_operand:SI 0 "register_operand" "")
5414 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5415 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
5417 "TARGET_HARD_MUL && TARGET_ARCH32"
5419 if (CONSTANT_P (operands[2]))
5423 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
5429 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
5434 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
5435 operands[2], GEN_INT (32)));
5441 (define_insn "smulsi3_highpart_v8plus"
5442 [(set (match_operand:SI 0 "register_operand" "=h,r")
5444 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5445 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5446 (match_operand:SI 3 "const_int_operand" "i,i"))))
5447 (clobber (match_scratch:SI 4 "=X,&h"))]
5450 smul\t%1, %2, %0\;srlx\t%0, %3, %0
5451 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
5452 [(set_attr "type" "multi")
5453 (set_attr "length" "2")])
5455 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
5458 [(set (match_operand:SI 0 "register_operand" "=h,r")
5461 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5462 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5463 (match_operand:SI 3 "const_int_operand" "i,i"))
5465 (clobber (match_scratch:SI 4 "=X,&h"))]
5468 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5469 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5470 [(set_attr "type" "multi")
5471 (set_attr "length" "2")])
5474 (define_insn "const_smulsi3_highpart_v8plus"
5475 [(set (match_operand:SI 0 "register_operand" "=h,r")
5477 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5478 (match_operand:DI 2 "small_int" "i,i"))
5479 (match_operand:SI 3 "const_int_operand" "i,i"))))
5480 (clobber (match_scratch:SI 4 "=X,&h"))]
5483 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5484 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5485 [(set_attr "type" "multi")
5486 (set_attr "length" "2")])
5489 (define_insn "*smulsi3_highpart_sp32"
5490 [(set (match_operand:SI 0 "register_operand" "=r")
5492 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5493 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
5496 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5497 [(set_attr "type" "multi")
5498 (set_attr "length" "2")])
5501 (define_insn "const_smulsi3_highpart"
5502 [(set (match_operand:SI 0 "register_operand" "=r")
5504 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5505 (match_operand:DI 2 "small_int" "i"))
5508 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5509 [(set_attr "type" "multi")
5510 (set_attr "length" "2")])
5512 (define_expand "umulsidi3"
5513 [(set (match_operand:DI 0 "register_operand" "")
5514 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5515 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
5518 if (CONSTANT_P (operands[2]))
5521 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
5523 else if (TARGET_ARCH32)
5524 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
5527 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
5533 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
5539 (define_insn "umulsidi3_v8plus"
5540 [(set (match_operand:DI 0 "register_operand" "=h,r")
5541 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5542 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5543 (clobber (match_scratch:SI 3 "=X,&h"))]
5546 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5547 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5548 [(set_attr "type" "multi")
5549 (set_attr "length" "2,3")])
5552 (define_insn "*umulsidi3_sp32"
5553 [(set (match_operand:DI 0 "register_operand" "=r")
5554 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5555 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5558 return TARGET_SPARCLET
5559 ? "umuld\t%1, %2, %L0"
5560 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
5563 (if_then_else (eq_attr "isa" "sparclet")
5564 (const_string "imul") (const_string "multi")))
5565 (set (attr "length")
5566 (if_then_else (eq_attr "isa" "sparclet")
5567 (const_int 1) (const_int 2)))])
5569 (define_insn "*umulsidi3_sp64"
5570 [(set (match_operand:DI 0 "register_operand" "=r")
5571 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5572 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5573 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5575 [(set_attr "type" "imul")])
5577 ;; Extra pattern, because sign_extend of a constant isn't valid.
5580 (define_insn "const_umulsidi3_sp32"
5581 [(set (match_operand:DI 0 "register_operand" "=r")
5582 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5583 (match_operand:DI 2 "uns_small_int" "")))]
5586 return TARGET_SPARCLET
5587 ? "umuld\t%1, %s2, %L0"
5588 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
5591 (if_then_else (eq_attr "isa" "sparclet")
5592 (const_string "imul") (const_string "multi")))
5593 (set (attr "length")
5594 (if_then_else (eq_attr "isa" "sparclet")
5595 (const_int 1) (const_int 2)))])
5597 (define_insn "const_umulsidi3_sp64"
5598 [(set (match_operand:DI 0 "register_operand" "=r")
5599 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5600 (match_operand:DI 2 "uns_small_int" "")))]
5601 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5603 [(set_attr "type" "imul")])
5606 (define_insn "const_umulsidi3_v8plus"
5607 [(set (match_operand:DI 0 "register_operand" "=h,r")
5608 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5609 (match_operand:DI 2 "uns_small_int" "")))
5610 (clobber (match_scratch:SI 3 "=X,h"))]
5613 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
5614 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5615 [(set_attr "type" "multi")
5616 (set_attr "length" "2,3")])
5618 (define_expand "umulsi3_highpart"
5619 [(set (match_operand:SI 0 "register_operand" "")
5621 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5622 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5624 "TARGET_HARD_MUL && TARGET_ARCH32"
5626 if (CONSTANT_P (operands[2]))
5630 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5636 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5641 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5642 operands[2], GEN_INT (32)));
5648 (define_insn "umulsi3_highpart_v8plus"
5649 [(set (match_operand:SI 0 "register_operand" "=h,r")
5651 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5652 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5653 (match_operand:SI 3 "const_int_operand" "i,i"))))
5654 (clobber (match_scratch:SI 4 "=X,h"))]
5657 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5658 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5659 [(set_attr "type" "multi")
5660 (set_attr "length" "2")])
5663 (define_insn "const_umulsi3_highpart_v8plus"
5664 [(set (match_operand:SI 0 "register_operand" "=h,r")
5666 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5667 (match_operand:DI 2 "uns_small_int" ""))
5668 (match_operand:SI 3 "const_int_operand" "i,i"))))
5669 (clobber (match_scratch:SI 4 "=X,h"))]
5672 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
5673 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
5674 [(set_attr "type" "multi")
5675 (set_attr "length" "2")])
5678 (define_insn "*umulsi3_highpart_sp32"
5679 [(set (match_operand:SI 0 "register_operand" "=r")
5681 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5682 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5685 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
5686 [(set_attr "type" "multi")
5687 (set_attr "length" "2")])
5690 (define_insn "const_umulsi3_highpart"
5691 [(set (match_operand:SI 0 "register_operand" "=r")
5693 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5694 (match_operand:DI 2 "uns_small_int" ""))
5697 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
5698 [(set_attr "type" "multi")
5699 (set_attr "length" "2")])
5701 ;; The v8 architecture specifies that there must be 3 instructions between
5702 ;; a y register write and a use of it for correct results.
5704 (define_expand "divsi3"
5705 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5706 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5707 (match_operand:SI 2 "input_operand" "rI,m")))
5708 (clobber (match_scratch:SI 3 "=&r,&r"))])]
5709 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5713 operands[3] = gen_reg_rtx(SImode);
5714 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5715 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5721 (define_insn "divsi3_sp32"
5722 [(set (match_operand:SI 0 "register_operand" "=r,r")
5723 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5724 (match_operand:SI 2 "input_operand" "rI,m")))
5725 (clobber (match_scratch:SI 3 "=&r,&r"))]
5726 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5729 if (which_alternative == 0)
5731 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
5733 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5736 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
5738 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
5740 [(set_attr "type" "multi")
5741 (set (attr "length")
5742 (if_then_else (eq_attr "isa" "v9")
5743 (const_int 4) (const_int 6)))])
5745 (define_insn "divsi3_sp64"
5746 [(set (match_operand:SI 0 "register_operand" "=r")
5747 (div:SI (match_operand:SI 1 "register_operand" "r")
5748 (match_operand:SI 2 "input_operand" "rI")))
5749 (use (match_operand:SI 3 "register_operand" "r"))]
5750 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5751 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5752 [(set_attr "type" "multi")
5753 (set_attr "length" "2")])
5755 (define_insn "divdi3"
5756 [(set (match_operand:DI 0 "register_operand" "=r")
5757 (div:DI (match_operand:DI 1 "register_operand" "r")
5758 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5761 [(set_attr "type" "idiv")])
5763 (define_insn "*cmp_sdiv_cc_set"
5765 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5766 (match_operand:SI 2 "arith_operand" "rI"))
5768 (set (match_operand:SI 0 "register_operand" "=r")
5769 (div:SI (match_dup 1) (match_dup 2)))
5770 (clobber (match_scratch:SI 3 "=&r"))]
5771 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5774 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
5776 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5778 [(set_attr "type" "multi")
5779 (set (attr "length")
5780 (if_then_else (eq_attr "isa" "v9")
5781 (const_int 3) (const_int 6)))])
5784 (define_expand "udivsi3"
5785 [(set (match_operand:SI 0 "register_operand" "")
5786 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
5787 (match_operand:SI 2 "input_operand" "")))]
5788 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5791 (define_insn "udivsi3_sp32"
5792 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5793 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
5794 (match_operand:SI 2 "input_operand" "rI,m,r")))]
5796 || TARGET_DEPRECATED_V8_INSNS)
5799 output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
5800 switch (which_alternative)
5803 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5805 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5807 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5810 [(set_attr "type" "multi")
5811 (set_attr "length" "5")])
5813 (define_insn "udivsi3_sp64"
5814 [(set (match_operand:SI 0 "register_operand" "=r")
5815 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
5816 (match_operand:SI 2 "input_operand" "rI")))]
5817 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5818 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5819 [(set_attr "type" "multi")
5820 (set_attr "length" "2")])
5822 (define_insn "udivdi3"
5823 [(set (match_operand:DI 0 "register_operand" "=r")
5824 (udiv:DI (match_operand:DI 1 "register_operand" "r")
5825 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5828 [(set_attr "type" "idiv")])
5830 (define_insn "*cmp_udiv_cc_set"
5832 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5833 (match_operand:SI 2 "arith_operand" "rI"))
5835 (set (match_operand:SI 0 "register_operand" "=r")
5836 (udiv:SI (match_dup 1) (match_dup 2)))]
5838 || TARGET_DEPRECATED_V8_INSNS"
5841 return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5843 return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5845 [(set_attr "type" "multi")
5846 (set (attr "length")
5847 (if_then_else (eq_attr "isa" "v9")
5848 (const_int 2) (const_int 5)))])
5850 ; sparclet multiply/accumulate insns
5852 (define_insn "*smacsi"
5853 [(set (match_operand:SI 0 "register_operand" "=r")
5854 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5855 (match_operand:SI 2 "arith_operand" "rI"))
5856 (match_operand:SI 3 "register_operand" "0")))]
5859 [(set_attr "type" "imul")])
5861 (define_insn "*smacdi"
5862 [(set (match_operand:DI 0 "register_operand" "=r")
5863 (plus:DI (mult:DI (sign_extend:DI
5864 (match_operand:SI 1 "register_operand" "%r"))
5866 (match_operand:SI 2 "register_operand" "r")))
5867 (match_operand:DI 3 "register_operand" "0")))]
5869 "smacd\t%1, %2, %L0"
5870 [(set_attr "type" "imul")])
5872 (define_insn "*umacdi"
5873 [(set (match_operand:DI 0 "register_operand" "=r")
5874 (plus:DI (mult:DI (zero_extend:DI
5875 (match_operand:SI 1 "register_operand" "%r"))
5877 (match_operand:SI 2 "register_operand" "r")))
5878 (match_operand:DI 3 "register_operand" "0")))]
5880 "umacd\t%1, %2, %L0"
5881 [(set_attr "type" "imul")])
5883 ;;- Boolean instructions
5884 ;; We define DImode `and' so with DImode `not' we can get
5885 ;; DImode `andn'. Other combinations are possible.
5887 (define_expand "anddi3"
5888 [(set (match_operand:DI 0 "register_operand" "")
5889 (and:DI (match_operand:DI 1 "arith_double_operand" "")
5890 (match_operand:DI 2 "arith_double_operand" "")))]
5894 (define_insn "*anddi3_sp32"
5895 [(set (match_operand:DI 0 "register_operand" "=r,b")
5896 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5897 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5902 [(set_attr "type" "*,fga")
5903 (set_attr "length" "2,*")
5904 (set_attr "fptype" "double")])
5906 (define_insn "*anddi3_sp64"
5907 [(set (match_operand:DI 0 "register_operand" "=r,b")
5908 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5909 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5914 [(set_attr "type" "*,fga")
5915 (set_attr "fptype" "double")])
5917 (define_insn "andsi3"
5918 [(set (match_operand:SI 0 "register_operand" "=r,d")
5919 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
5920 (match_operand:SI 2 "arith_operand" "rI,d")))]
5925 [(set_attr "type" "*,fga")])
5928 [(set (match_operand:SI 0 "register_operand" "")
5929 (and:SI (match_operand:SI 1 "register_operand" "")
5930 (match_operand:SI 2 "" "")))
5931 (clobber (match_operand:SI 3 "register_operand" ""))]
5932 "GET_CODE (operands[2]) == CONST_INT
5933 && !SMALL_INT32 (operands[2])
5934 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
5935 [(set (match_dup 3) (match_dup 4))
5936 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5938 operands[4] = GEN_INT (~INTVAL (operands[2]));
5941 ;; Split DImode logical operations requiring two instructions.
5943 [(set (match_operand:DI 0 "register_operand" "")
5944 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
5945 [(match_operand:DI 2 "register_operand" "")
5946 (match_operand:DI 3 "arith_double_operand" "")]))]
5949 && ((GET_CODE (operands[0]) == REG
5950 && REGNO (operands[0]) < 32)
5951 || (GET_CODE (operands[0]) == SUBREG
5952 && GET_CODE (SUBREG_REG (operands[0])) == REG
5953 && REGNO (SUBREG_REG (operands[0])) < 32))"
5954 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5955 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5957 operands[4] = gen_highpart (SImode, operands[0]);
5958 operands[5] = gen_lowpart (SImode, operands[0]);
5959 operands[6] = gen_highpart (SImode, operands[2]);
5960 operands[7] = gen_lowpart (SImode, operands[2]);
5961 #if HOST_BITS_PER_WIDE_INT == 32
5962 if (GET_CODE (operands[3]) == CONST_INT)
5964 if (INTVAL (operands[3]) < 0)
5965 operands[8] = constm1_rtx;
5967 operands[8] = const0_rtx;
5971 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
5972 operands[9] = gen_lowpart (SImode, operands[3]);
5975 (define_insn_and_split "*and_not_di_sp32"
5976 [(set (match_operand:DI 0 "register_operand" "=r,b")
5977 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5978 (match_operand:DI 2 "register_operand" "r,b")))]
5982 fandnot1\t%1, %2, %0"
5983 "&& reload_completed
5984 && ((GET_CODE (operands[0]) == REG
5985 && REGNO (operands[0]) < 32)
5986 || (GET_CODE (operands[0]) == SUBREG
5987 && GET_CODE (SUBREG_REG (operands[0])) == REG
5988 && REGNO (SUBREG_REG (operands[0])) < 32))"
5989 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5990 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5991 "operands[3] = gen_highpart (SImode, operands[0]);
5992 operands[4] = gen_highpart (SImode, operands[1]);
5993 operands[5] = gen_highpart (SImode, operands[2]);
5994 operands[6] = gen_lowpart (SImode, operands[0]);
5995 operands[7] = gen_lowpart (SImode, operands[1]);
5996 operands[8] = gen_lowpart (SImode, operands[2]);"
5997 [(set_attr "type" "*,fga")
5998 (set_attr "length" "2,*")
5999 (set_attr "fptype" "double")])
6001 (define_insn "*and_not_di_sp64"
6002 [(set (match_operand:DI 0 "register_operand" "=r,b")
6003 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6004 (match_operand:DI 2 "register_operand" "r,b")))]
6008 fandnot1\t%1, %2, %0"
6009 [(set_attr "type" "*,fga")
6010 (set_attr "fptype" "double")])
6012 (define_insn "*and_not_si"
6013 [(set (match_operand:SI 0 "register_operand" "=r,d")
6014 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6015 (match_operand:SI 2 "register_operand" "r,d")))]
6019 fandnot1s\t%1, %2, %0"
6020 [(set_attr "type" "*,fga")])
6022 (define_expand "iordi3"
6023 [(set (match_operand:DI 0 "register_operand" "")
6024 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6025 (match_operand:DI 2 "arith_double_operand" "")))]
6029 (define_insn "*iordi3_sp32"
6030 [(set (match_operand:DI 0 "register_operand" "=r,b")
6031 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6032 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6037 [(set_attr "type" "*,fga")
6038 (set_attr "length" "2,*")
6039 (set_attr "fptype" "double")])
6041 (define_insn "*iordi3_sp64"
6042 [(set (match_operand:DI 0 "register_operand" "=r,b")
6043 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6044 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6049 [(set_attr "type" "*,fga")
6050 (set_attr "fptype" "double")])
6052 (define_insn "iorsi3"
6053 [(set (match_operand:SI 0 "register_operand" "=r,d")
6054 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6055 (match_operand:SI 2 "arith_operand" "rI,d")))]
6060 [(set_attr "type" "*,fga")])
6063 [(set (match_operand:SI 0 "register_operand" "")
6064 (ior:SI (match_operand:SI 1 "register_operand" "")
6065 (match_operand:SI 2 "" "")))
6066 (clobber (match_operand:SI 3 "register_operand" ""))]
6067 "GET_CODE (operands[2]) == CONST_INT
6068 && !SMALL_INT32 (operands[2])
6069 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6070 [(set (match_dup 3) (match_dup 4))
6071 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6073 operands[4] = GEN_INT (~INTVAL (operands[2]));
6076 (define_insn_and_split "*or_not_di_sp32"
6077 [(set (match_operand:DI 0 "register_operand" "=r,b")
6078 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6079 (match_operand:DI 2 "register_operand" "r,b")))]
6083 fornot1\t%1, %2, %0"
6084 "&& reload_completed
6085 && ((GET_CODE (operands[0]) == REG
6086 && REGNO (operands[0]) < 32)
6087 || (GET_CODE (operands[0]) == SUBREG
6088 && GET_CODE (SUBREG_REG (operands[0])) == REG
6089 && REGNO (SUBREG_REG (operands[0])) < 32))"
6090 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6091 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6092 "operands[3] = gen_highpart (SImode, operands[0]);
6093 operands[4] = gen_highpart (SImode, operands[1]);
6094 operands[5] = gen_highpart (SImode, operands[2]);
6095 operands[6] = gen_lowpart (SImode, operands[0]);
6096 operands[7] = gen_lowpart (SImode, operands[1]);
6097 operands[8] = gen_lowpart (SImode, operands[2]);"
6098 [(set_attr "type" "*,fga")
6099 (set_attr "length" "2,*")
6100 (set_attr "fptype" "double")])
6102 (define_insn "*or_not_di_sp64"
6103 [(set (match_operand:DI 0 "register_operand" "=r,b")
6104 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6105 (match_operand:DI 2 "register_operand" "r,b")))]
6109 fornot1\t%1, %2, %0"
6110 [(set_attr "type" "*,fga")
6111 (set_attr "fptype" "double")])
6113 (define_insn "*or_not_si"
6114 [(set (match_operand:SI 0 "register_operand" "=r,d")
6115 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6116 (match_operand:SI 2 "register_operand" "r,d")))]
6120 fornot1s\t%1, %2, %0"
6121 [(set_attr "type" "*,fga")])
6123 (define_expand "xordi3"
6124 [(set (match_operand:DI 0 "register_operand" "")
6125 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6126 (match_operand:DI 2 "arith_double_operand" "")))]
6130 (define_insn "*xordi3_sp32"
6131 [(set (match_operand:DI 0 "register_operand" "=r,b")
6132 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6133 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6138 [(set_attr "type" "*,fga")
6139 (set_attr "length" "2,*")
6140 (set_attr "fptype" "double")])
6142 (define_insn "*xordi3_sp64"
6143 [(set (match_operand:DI 0 "register_operand" "=r,b")
6144 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6145 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6150 [(set_attr "type" "*,fga")
6151 (set_attr "fptype" "double")])
6153 (define_insn "*xordi3_sp64_dbl"
6154 [(set (match_operand:DI 0 "register_operand" "=r")
6155 (xor:DI (match_operand:DI 1 "register_operand" "r")
6156 (match_operand:DI 2 "const64_operand" "")))]
6158 && HOST_BITS_PER_WIDE_INT != 64)"
6161 (define_insn "xorsi3"
6162 [(set (match_operand:SI 0 "register_operand" "=r,d")
6163 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6164 (match_operand:SI 2 "arith_operand" "rI,d")))]
6169 [(set_attr "type" "*,fga")])
6172 [(set (match_operand:SI 0 "register_operand" "")
6173 (xor:SI (match_operand:SI 1 "register_operand" "")
6174 (match_operand:SI 2 "" "")))
6175 (clobber (match_operand:SI 3 "register_operand" ""))]
6176 "GET_CODE (operands[2]) == CONST_INT
6177 && !SMALL_INT32 (operands[2])
6178 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6179 [(set (match_dup 3) (match_dup 4))
6180 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6182 operands[4] = GEN_INT (~INTVAL (operands[2]));
6186 [(set (match_operand:SI 0 "register_operand" "")
6187 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6188 (match_operand:SI 2 "" ""))))
6189 (clobber (match_operand:SI 3 "register_operand" ""))]
6190 "GET_CODE (operands[2]) == CONST_INT
6191 && !SMALL_INT32 (operands[2])
6192 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6193 [(set (match_dup 3) (match_dup 4))
6194 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6196 operands[4] = GEN_INT (~INTVAL (operands[2]));
6199 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6200 ;; Combine now canonicalizes to the rightmost expression.
6201 (define_insn_and_split "*xor_not_di_sp32"
6202 [(set (match_operand:DI 0 "register_operand" "=r,b")
6203 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6204 (match_operand:DI 2 "register_operand" "r,b"))))]
6209 "&& reload_completed
6210 && ((GET_CODE (operands[0]) == REG
6211 && REGNO (operands[0]) < 32)
6212 || (GET_CODE (operands[0]) == SUBREG
6213 && GET_CODE (SUBREG_REG (operands[0])) == REG
6214 && REGNO (SUBREG_REG (operands[0])) < 32))"
6215 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6216 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6217 "operands[3] = gen_highpart (SImode, operands[0]);
6218 operands[4] = gen_highpart (SImode, operands[1]);
6219 operands[5] = gen_highpart (SImode, operands[2]);
6220 operands[6] = gen_lowpart (SImode, operands[0]);
6221 operands[7] = gen_lowpart (SImode, operands[1]);
6222 operands[8] = gen_lowpart (SImode, operands[2]);"
6223 [(set_attr "type" "*,fga")
6224 (set_attr "length" "2,*")
6225 (set_attr "fptype" "double")])
6227 (define_insn "*xor_not_di_sp64"
6228 [(set (match_operand:DI 0 "register_operand" "=r,b")
6229 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6230 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6235 [(set_attr "type" "*,fga")
6236 (set_attr "fptype" "double")])
6238 (define_insn "*xor_not_si"
6239 [(set (match_operand:SI 0 "register_operand" "=r,d")
6240 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6241 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6246 [(set_attr "type" "*,fga")])
6248 ;; These correspond to the above in the case where we also (or only)
6249 ;; want to set the condition code.
6251 (define_insn "*cmp_cc_arith_op"
6254 (match_operator:SI 2 "cc_arithop"
6255 [(match_operand:SI 0 "arith_operand" "%r")
6256 (match_operand:SI 1 "arith_operand" "rI")])
6259 "%A2cc\t%0, %1, %%g0"
6260 [(set_attr "type" "compare")])
6262 (define_insn "*cmp_ccx_arith_op"
6265 (match_operator:DI 2 "cc_arithop"
6266 [(match_operand:DI 0 "arith_double_operand" "%r")
6267 (match_operand:DI 1 "arith_double_operand" "rHI")])
6270 "%A2cc\t%0, %1, %%g0"
6271 [(set_attr "type" "compare")])
6273 (define_insn "*cmp_cc_arith_op_set"
6276 (match_operator:SI 3 "cc_arithop"
6277 [(match_operand:SI 1 "arith_operand" "%r")
6278 (match_operand:SI 2 "arith_operand" "rI")])
6280 (set (match_operand:SI 0 "register_operand" "=r")
6281 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6282 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6284 [(set_attr "type" "compare")])
6286 (define_insn "*cmp_ccx_arith_op_set"
6289 (match_operator:DI 3 "cc_arithop"
6290 [(match_operand:DI 1 "arith_double_operand" "%r")
6291 (match_operand:DI 2 "arith_double_operand" "rHI")])
6293 (set (match_operand:DI 0 "register_operand" "=r")
6294 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6295 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6297 [(set_attr "type" "compare")])
6299 (define_insn "*cmp_cc_xor_not"
6302 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6303 (match_operand:SI 1 "arith_operand" "rI")))
6306 "xnorcc\t%r0, %1, %%g0"
6307 [(set_attr "type" "compare")])
6309 (define_insn "*cmp_ccx_xor_not"
6312 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6313 (match_operand:DI 1 "arith_double_operand" "rHI")))
6316 "xnorcc\t%r0, %1, %%g0"
6317 [(set_attr "type" "compare")])
6319 (define_insn "*cmp_cc_xor_not_set"
6322 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6323 (match_operand:SI 2 "arith_operand" "rI")))
6325 (set (match_operand:SI 0 "register_operand" "=r")
6326 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6328 "xnorcc\t%r1, %2, %0"
6329 [(set_attr "type" "compare")])
6331 (define_insn "*cmp_ccx_xor_not_set"
6334 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6335 (match_operand:DI 2 "arith_double_operand" "rHI")))
6337 (set (match_operand:DI 0 "register_operand" "=r")
6338 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6340 "xnorcc\t%r1, %2, %0"
6341 [(set_attr "type" "compare")])
6343 (define_insn "*cmp_cc_arith_op_not"
6346 (match_operator:SI 2 "cc_arithopn"
6347 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
6348 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
6351 "%B2cc\t%r1, %0, %%g0"
6352 [(set_attr "type" "compare")])
6354 (define_insn "*cmp_ccx_arith_op_not"
6357 (match_operator:DI 2 "cc_arithopn"
6358 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6359 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
6362 "%B2cc\t%r1, %0, %%g0"
6363 [(set_attr "type" "compare")])
6365 (define_insn "*cmp_cc_arith_op_not_set"
6368 (match_operator:SI 3 "cc_arithopn"
6369 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
6370 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
6372 (set (match_operand:SI 0 "register_operand" "=r")
6373 (match_operator:SI 4 "cc_arithopn"
6374 [(not:SI (match_dup 1)) (match_dup 2)]))]
6375 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6376 "%B3cc\t%r2, %1, %0"
6377 [(set_attr "type" "compare")])
6379 (define_insn "*cmp_ccx_arith_op_not_set"
6382 (match_operator:DI 3 "cc_arithopn"
6383 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6384 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
6386 (set (match_operand:DI 0 "register_operand" "=r")
6387 (match_operator:DI 4 "cc_arithopn"
6388 [(not:DI (match_dup 1)) (match_dup 2)]))]
6389 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6390 "%B3cc\t%r2, %1, %0"
6391 [(set_attr "type" "compare")])
6393 ;; We cannot use the "neg" pseudo insn because the Sun assembler
6394 ;; does not know how to make it work for constants.
6396 (define_expand "negdi2"
6397 [(set (match_operand:DI 0 "register_operand" "=r")
6398 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6401 if (! TARGET_ARCH64)
6403 emit_insn (gen_rtx_PARALLEL
6406 gen_rtx_SET (VOIDmode, operand0,
6407 gen_rtx_NEG (DImode, operand1)),
6408 gen_rtx_CLOBBER (VOIDmode,
6409 gen_rtx_REG (CCmode,
6415 (define_insn_and_split "*negdi2_sp32"
6416 [(set (match_operand:DI 0 "register_operand" "=r")
6417 (neg:DI (match_operand:DI 1 "register_operand" "r")))
6418 (clobber (reg:CC 100))]
6421 "&& reload_completed"
6422 [(parallel [(set (reg:CC_NOOV 100)
6423 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
6425 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
6426 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
6427 (ltu:SI (reg:CC 100) (const_int 0))))]
6428 "operands[2] = gen_highpart (SImode, operands[0]);
6429 operands[3] = gen_highpart (SImode, operands[1]);
6430 operands[4] = gen_lowpart (SImode, operands[0]);
6431 operands[5] = gen_lowpart (SImode, operands[1]);"
6432 [(set_attr "length" "2")])
6434 (define_insn "*negdi2_sp64"
6435 [(set (match_operand:DI 0 "register_operand" "=r")
6436 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6438 "sub\t%%g0, %1, %0")
6440 (define_insn "negsi2"
6441 [(set (match_operand:SI 0 "register_operand" "=r")
6442 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
6444 "sub\t%%g0, %1, %0")
6446 (define_insn "*cmp_cc_neg"
6447 [(set (reg:CC_NOOV 100)
6448 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
6451 "subcc\t%%g0, %0, %%g0"
6452 [(set_attr "type" "compare")])
6454 (define_insn "*cmp_ccx_neg"
6455 [(set (reg:CCX_NOOV 100)
6456 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6459 "subcc\t%%g0, %0, %%g0"
6460 [(set_attr "type" "compare")])
6462 (define_insn "*cmp_cc_set_neg"
6463 [(set (reg:CC_NOOV 100)
6464 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
6466 (set (match_operand:SI 0 "register_operand" "=r")
6467 (neg:SI (match_dup 1)))]
6469 "subcc\t%%g0, %1, %0"
6470 [(set_attr "type" "compare")])
6472 (define_insn "*cmp_ccx_set_neg"
6473 [(set (reg:CCX_NOOV 100)
6474 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6476 (set (match_operand:DI 0 "register_operand" "=r")
6477 (neg:DI (match_dup 1)))]
6479 "subcc\t%%g0, %1, %0"
6480 [(set_attr "type" "compare")])
6482 ;; We cannot use the "not" pseudo insn because the Sun assembler
6483 ;; does not know how to make it work for constants.
6484 (define_expand "one_cmpldi2"
6485 [(set (match_operand:DI 0 "register_operand" "")
6486 (not:DI (match_operand:DI 1 "register_operand" "")))]
6490 (define_insn_and_split "*one_cmpldi2_sp32"
6491 [(set (match_operand:DI 0 "register_operand" "=r,b")
6492 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
6497 "&& reload_completed
6498 && ((GET_CODE (operands[0]) == REG
6499 && REGNO (operands[0]) < 32)
6500 || (GET_CODE (operands[0]) == SUBREG
6501 && GET_CODE (SUBREG_REG (operands[0])) == REG
6502 && REGNO (SUBREG_REG (operands[0])) < 32))"
6503 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
6504 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
6505 "operands[2] = gen_highpart (SImode, operands[0]);
6506 operands[3] = gen_highpart (SImode, operands[1]);
6507 operands[4] = gen_lowpart (SImode, operands[0]);
6508 operands[5] = gen_lowpart (SImode, operands[1]);"
6509 [(set_attr "type" "*,fga")
6510 (set_attr "length" "2,*")
6511 (set_attr "fptype" "double")])
6513 (define_insn "*one_cmpldi2_sp64"
6514 [(set (match_operand:DI 0 "register_operand" "=r,b")
6515 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
6520 [(set_attr "type" "*,fga")
6521 (set_attr "fptype" "double")])
6523 (define_insn "one_cmplsi2"
6524 [(set (match_operand:SI 0 "register_operand" "=r,d")
6525 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
6530 [(set_attr "type" "*,fga")])
6532 (define_insn "*cmp_cc_not"
6534 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
6537 "xnorcc\t%%g0, %0, %%g0"
6538 [(set_attr "type" "compare")])
6540 (define_insn "*cmp_ccx_not"
6542 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6545 "xnorcc\t%%g0, %0, %%g0"
6546 [(set_attr "type" "compare")])
6548 (define_insn "*cmp_cc_set_not"
6550 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
6552 (set (match_operand:SI 0 "register_operand" "=r")
6553 (not:SI (match_dup 1)))]
6555 "xnorcc\t%%g0, %1, %0"
6556 [(set_attr "type" "compare")])
6558 (define_insn "*cmp_ccx_set_not"
6560 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6562 (set (match_operand:DI 0 "register_operand" "=r")
6563 (not:DI (match_dup 1)))]
6565 "xnorcc\t%%g0, %1, %0"
6566 [(set_attr "type" "compare")])
6568 (define_insn "*cmp_cc_set"
6569 [(set (match_operand:SI 0 "register_operand" "=r")
6570 (match_operand:SI 1 "register_operand" "r"))
6572 (compare:CC (match_dup 1)
6576 [(set_attr "type" "compare")])
6578 (define_insn "*cmp_ccx_set64"
6579 [(set (match_operand:DI 0 "register_operand" "=r")
6580 (match_operand:DI 1 "register_operand" "r"))
6582 (compare:CCX (match_dup 1)
6586 [(set_attr "type" "compare")])
6588 ;; Floating point arithmetic instructions.
6590 (define_expand "addtf3"
6591 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6592 (plus:TF (match_operand:TF 1 "general_operand" "")
6593 (match_operand:TF 2 "general_operand" "")))]
6594 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6595 "emit_tfmode_binop (PLUS, operands); DONE;")
6597 (define_insn "*addtf3_hq"
6598 [(set (match_operand:TF 0 "register_operand" "=e")
6599 (plus:TF (match_operand:TF 1 "register_operand" "e")
6600 (match_operand:TF 2 "register_operand" "e")))]
6601 "TARGET_FPU && TARGET_HARD_QUAD"
6603 [(set_attr "type" "fp")])
6605 (define_insn "adddf3"
6606 [(set (match_operand:DF 0 "register_operand" "=e")
6607 (plus:DF (match_operand:DF 1 "register_operand" "e")
6608 (match_operand:DF 2 "register_operand" "e")))]
6611 [(set_attr "type" "fp")
6612 (set_attr "fptype" "double")])
6614 (define_insn "addsf3"
6615 [(set (match_operand:SF 0 "register_operand" "=f")
6616 (plus:SF (match_operand:SF 1 "register_operand" "f")
6617 (match_operand:SF 2 "register_operand" "f")))]
6620 [(set_attr "type" "fp")])
6622 (define_expand "subtf3"
6623 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6624 (minus:TF (match_operand:TF 1 "general_operand" "")
6625 (match_operand:TF 2 "general_operand" "")))]
6626 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6627 "emit_tfmode_binop (MINUS, operands); DONE;")
6629 (define_insn "*subtf3_hq"
6630 [(set (match_operand:TF 0 "register_operand" "=e")
6631 (minus:TF (match_operand:TF 1 "register_operand" "e")
6632 (match_operand:TF 2 "register_operand" "e")))]
6633 "TARGET_FPU && TARGET_HARD_QUAD"
6635 [(set_attr "type" "fp")])
6637 (define_insn "subdf3"
6638 [(set (match_operand:DF 0 "register_operand" "=e")
6639 (minus:DF (match_operand:DF 1 "register_operand" "e")
6640 (match_operand:DF 2 "register_operand" "e")))]
6643 [(set_attr "type" "fp")
6644 (set_attr "fptype" "double")])
6646 (define_insn "subsf3"
6647 [(set (match_operand:SF 0 "register_operand" "=f")
6648 (minus:SF (match_operand:SF 1 "register_operand" "f")
6649 (match_operand:SF 2 "register_operand" "f")))]
6652 [(set_attr "type" "fp")])
6654 (define_expand "multf3"
6655 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6656 (mult:TF (match_operand:TF 1 "general_operand" "")
6657 (match_operand:TF 2 "general_operand" "")))]
6658 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6659 "emit_tfmode_binop (MULT, operands); DONE;")
6661 (define_insn "*multf3_hq"
6662 [(set (match_operand:TF 0 "register_operand" "=e")
6663 (mult:TF (match_operand:TF 1 "register_operand" "e")
6664 (match_operand:TF 2 "register_operand" "e")))]
6665 "TARGET_FPU && TARGET_HARD_QUAD"
6667 [(set_attr "type" "fpmul")])
6669 (define_insn "muldf3"
6670 [(set (match_operand:DF 0 "register_operand" "=e")
6671 (mult:DF (match_operand:DF 1 "register_operand" "e")
6672 (match_operand:DF 2 "register_operand" "e")))]
6675 [(set_attr "type" "fpmul")
6676 (set_attr "fptype" "double")])
6678 (define_insn "mulsf3"
6679 [(set (match_operand:SF 0 "register_operand" "=f")
6680 (mult:SF (match_operand:SF 1 "register_operand" "f")
6681 (match_operand:SF 2 "register_operand" "f")))]
6684 [(set_attr "type" "fpmul")])
6686 (define_insn "*muldf3_extend"
6687 [(set (match_operand:DF 0 "register_operand" "=e")
6688 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6689 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6690 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6691 "fsmuld\t%1, %2, %0"
6692 [(set_attr "type" "fpmul")
6693 (set_attr "fptype" "double")])
6695 (define_insn "*multf3_extend"
6696 [(set (match_operand:TF 0 "register_operand" "=e")
6697 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6698 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6699 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6700 "fdmulq\t%1, %2, %0"
6701 [(set_attr "type" "fpmul")])
6703 (define_expand "divtf3"
6704 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6705 (div:TF (match_operand:TF 1 "general_operand" "")
6706 (match_operand:TF 2 "general_operand" "")))]
6707 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6708 "emit_tfmode_binop (DIV, operands); DONE;")
6710 ;; don't have timing for quad-prec. divide.
6711 (define_insn "*divtf3_hq"
6712 [(set (match_operand:TF 0 "register_operand" "=e")
6713 (div:TF (match_operand:TF 1 "register_operand" "e")
6714 (match_operand:TF 2 "register_operand" "e")))]
6715 "TARGET_FPU && TARGET_HARD_QUAD"
6717 [(set_attr "type" "fpdivd")])
6719 (define_insn "divdf3"
6720 [(set (match_operand:DF 0 "register_operand" "=e")
6721 (div:DF (match_operand:DF 1 "register_operand" "e")
6722 (match_operand:DF 2 "register_operand" "e")))]
6725 [(set_attr "type" "fpdivd")
6726 (set_attr "fptype" "double")])
6728 (define_insn "divsf3"
6729 [(set (match_operand:SF 0 "register_operand" "=f")
6730 (div:SF (match_operand:SF 1 "register_operand" "f")
6731 (match_operand:SF 2 "register_operand" "f")))]
6734 [(set_attr "type" "fpdivs")])
6736 (define_expand "negtf2"
6737 [(set (match_operand:TF 0 "register_operand" "=e,e")
6738 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6742 (define_insn_and_split "*negtf2_notv9"
6743 [(set (match_operand:TF 0 "register_operand" "=e,e")
6744 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6745 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6751 "&& reload_completed
6752 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6753 [(set (match_dup 2) (neg:SF (match_dup 3)))
6754 (set (match_dup 4) (match_dup 5))
6755 (set (match_dup 6) (match_dup 7))]
6756 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6757 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6758 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6759 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6760 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6761 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6762 [(set_attr "type" "fpmove,*")
6763 (set_attr "length" "*,2")])
6765 (define_insn_and_split "*negtf2_v9"
6766 [(set (match_operand:TF 0 "register_operand" "=e,e")
6767 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6768 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6769 "TARGET_FPU && TARGET_V9"
6773 "&& reload_completed
6774 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6775 [(set (match_dup 2) (neg:DF (match_dup 3)))
6776 (set (match_dup 4) (match_dup 5))]
6777 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6778 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6779 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6780 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6781 [(set_attr "type" "fpmove,*")
6782 (set_attr "length" "*,2")
6783 (set_attr "fptype" "double")])
6785 (define_expand "negdf2"
6786 [(set (match_operand:DF 0 "register_operand" "")
6787 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6791 (define_insn_and_split "*negdf2_notv9"
6792 [(set (match_operand:DF 0 "register_operand" "=e,e")
6793 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6794 "TARGET_FPU && ! TARGET_V9"
6798 "&& reload_completed
6799 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6800 [(set (match_dup 2) (neg:SF (match_dup 3)))
6801 (set (match_dup 4) (match_dup 5))]
6802 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6803 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6804 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6805 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6806 [(set_attr "type" "fpmove,*")
6807 (set_attr "length" "*,2")])
6809 (define_insn "*negdf2_v9"
6810 [(set (match_operand:DF 0 "register_operand" "=e")
6811 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6812 "TARGET_FPU && TARGET_V9"
6814 [(set_attr "type" "fpmove")
6815 (set_attr "fptype" "double")])
6817 (define_insn "negsf2"
6818 [(set (match_operand:SF 0 "register_operand" "=f")
6819 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6822 [(set_attr "type" "fpmove")])
6824 (define_expand "abstf2"
6825 [(set (match_operand:TF 0 "register_operand" "")
6826 (abs:TF (match_operand:TF 1 "register_operand" "")))]
6830 (define_insn_and_split "*abstf2_notv9"
6831 [(set (match_operand:TF 0 "register_operand" "=e,e")
6832 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6833 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6834 "TARGET_FPU && ! TARGET_V9"
6838 "&& reload_completed
6839 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6840 [(set (match_dup 2) (abs:SF (match_dup 3)))
6841 (set (match_dup 4) (match_dup 5))
6842 (set (match_dup 6) (match_dup 7))]
6843 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6844 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6845 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6846 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6847 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6848 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6849 [(set_attr "type" "fpmove,*")
6850 (set_attr "length" "*,2")])
6852 (define_insn "*abstf2_hq_v9"
6853 [(set (match_operand:TF 0 "register_operand" "=e,e")
6854 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6855 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6859 [(set_attr "type" "fpmove")
6860 (set_attr "fptype" "double,*")])
6862 (define_insn_and_split "*abstf2_v9"
6863 [(set (match_operand:TF 0 "register_operand" "=e,e")
6864 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6865 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6869 "&& reload_completed
6870 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6871 [(set (match_dup 2) (abs:DF (match_dup 3)))
6872 (set (match_dup 4) (match_dup 5))]
6873 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6874 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6875 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6876 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6877 [(set_attr "type" "fpmove,*")
6878 (set_attr "length" "*,2")
6879 (set_attr "fptype" "double,*")])
6881 (define_expand "absdf2"
6882 [(set (match_operand:DF 0 "register_operand" "")
6883 (abs:DF (match_operand:DF 1 "register_operand" "")))]
6887 (define_insn_and_split "*absdf2_notv9"
6888 [(set (match_operand:DF 0 "register_operand" "=e,e")
6889 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6890 "TARGET_FPU && ! TARGET_V9"
6894 "&& reload_completed
6895 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6896 [(set (match_dup 2) (abs:SF (match_dup 3)))
6897 (set (match_dup 4) (match_dup 5))]
6898 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6899 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6900 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6901 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6902 [(set_attr "type" "fpmove,*")
6903 (set_attr "length" "*,2")])
6905 (define_insn "*absdf2_v9"
6906 [(set (match_operand:DF 0 "register_operand" "=e")
6907 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6908 "TARGET_FPU && TARGET_V9"
6910 [(set_attr "type" "fpmove")
6911 (set_attr "fptype" "double")])
6913 (define_insn "abssf2"
6914 [(set (match_operand:SF 0 "register_operand" "=f")
6915 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6918 [(set_attr "type" "fpmove")])
6920 (define_expand "sqrttf2"
6921 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6922 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6923 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6924 "emit_tfmode_unop (SQRT, operands); DONE;")
6926 (define_insn "*sqrttf2_hq"
6927 [(set (match_operand:TF 0 "register_operand" "=e")
6928 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6929 "TARGET_FPU && TARGET_HARD_QUAD"
6931 [(set_attr "type" "fpsqrtd")])
6933 (define_insn "sqrtdf2"
6934 [(set (match_operand:DF 0 "register_operand" "=e")
6935 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6938 [(set_attr "type" "fpsqrtd")
6939 (set_attr "fptype" "double")])
6941 (define_insn "sqrtsf2"
6942 [(set (match_operand:SF 0 "register_operand" "=f")
6943 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6946 [(set_attr "type" "fpsqrts")])
6948 ;;- arithmetic shift instructions
6950 (define_insn "ashlsi3"
6951 [(set (match_operand:SI 0 "register_operand" "=r")
6952 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6953 (match_operand:SI 2 "arith_operand" "rI")))]
6956 if (GET_CODE (operands[2]) == CONST_INT)
6957 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6958 return "sll\t%1, %2, %0";
6961 (if_then_else (match_operand 2 "const1_operand" "")
6962 (const_string "ialu") (const_string "shift")))])
6964 (define_expand "ashldi3"
6965 [(set (match_operand:DI 0 "register_operand" "=r")
6966 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6967 (match_operand:SI 2 "arith_operand" "rI")))]
6968 "TARGET_ARCH64 || TARGET_V8PLUS"
6970 if (! TARGET_ARCH64)
6972 if (GET_CODE (operands[2]) == CONST_INT)
6974 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6979 (define_insn "*ashldi3_sp64"
6980 [(set (match_operand:DI 0 "register_operand" "=r")
6981 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6982 (match_operand:SI 2 "arith_operand" "rI")))]
6985 if (GET_CODE (operands[2]) == CONST_INT)
6986 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6987 return "sllx\t%1, %2, %0";
6990 (if_then_else (match_operand 2 "const1_operand" "")
6991 (const_string "ialu") (const_string "shift")))])
6994 (define_insn "ashldi3_v8plus"
6995 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6996 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6997 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6998 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7000 "* return output_v8plus_shift (operands, insn, \"sllx\");"
7001 [(set_attr "type" "multi")
7002 (set_attr "length" "5,5,6")])
7004 ;; Optimize (1LL<<x)-1
7005 ;; XXX this also needs to be fixed to handle equal subregs
7006 ;; XXX first before we could re-enable it.
7008 ; [(set (match_operand:DI 0 "register_operand" "=h")
7009 ; (plus:DI (ashift:DI (const_int 1)
7010 ; (match_operand:SI 1 "arith_operand" "rI"))
7012 ; "0 && TARGET_V8PLUS"
7014 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
7015 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
7016 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
7018 ; [(set_attr "type" "multi")
7019 ; (set_attr "length" "4")])
7021 (define_insn "*cmp_cc_ashift_1"
7022 [(set (reg:CC_NOOV 100)
7023 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
7027 "addcc\t%0, %0, %%g0"
7028 [(set_attr "type" "compare")])
7030 (define_insn "*cmp_cc_set_ashift_1"
7031 [(set (reg:CC_NOOV 100)
7032 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7035 (set (match_operand:SI 0 "register_operand" "=r")
7036 (ashift:SI (match_dup 1) (const_int 1)))]
7039 [(set_attr "type" "compare")])
7041 (define_insn "ashrsi3"
7042 [(set (match_operand:SI 0 "register_operand" "=r")
7043 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7044 (match_operand:SI 2 "arith_operand" "rI")))]
7047 if (GET_CODE (operands[2]) == CONST_INT)
7048 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7049 return "sra\t%1, %2, %0";
7051 [(set_attr "type" "shift")])
7053 (define_insn "*ashrsi3_extend"
7054 [(set (match_operand:DI 0 "register_operand" "=r")
7055 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7056 (match_operand:SI 2 "arith_operand" "r"))))]
7059 [(set_attr "type" "shift")])
7061 ;; This handles the case as above, but with constant shift instead of
7062 ;; register. Combiner "simplifies" it for us a little bit though.
7063 (define_insn "*ashrsi3_extend2"
7064 [(set (match_operand:DI 0 "register_operand" "=r")
7065 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7067 (match_operand:SI 2 "small_int_or_double" "n")))]
7069 && ((GET_CODE (operands[2]) == CONST_INT
7070 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7071 || (GET_CODE (operands[2]) == CONST_DOUBLE
7072 && !CONST_DOUBLE_HIGH (operands[2])
7073 && CONST_DOUBLE_LOW (operands[2]) >= 32
7074 && CONST_DOUBLE_LOW (operands[2]) < 64))"
7076 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7078 return "sra\t%1, %2, %0";
7080 [(set_attr "type" "shift")])
7082 (define_expand "ashrdi3"
7083 [(set (match_operand:DI 0 "register_operand" "=r")
7084 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7085 (match_operand:SI 2 "arith_operand" "rI")))]
7086 "TARGET_ARCH64 || TARGET_V8PLUS"
7088 if (! TARGET_ARCH64)
7090 if (GET_CODE (operands[2]) == CONST_INT)
7091 FAIL; /* prefer generic code in this case */
7092 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
7097 (define_insn "*ashrdi3_sp64"
7098 [(set (match_operand:DI 0 "register_operand" "=r")
7099 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7100 (match_operand:SI 2 "arith_operand" "rI")))]
7104 if (GET_CODE (operands[2]) == CONST_INT)
7105 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7106 return "srax\t%1, %2, %0";
7108 [(set_attr "type" "shift")])
7111 (define_insn "ashrdi3_v8plus"
7112 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7113 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7114 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7115 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7117 "* return output_v8plus_shift (operands, insn, \"srax\");"
7118 [(set_attr "type" "multi")
7119 (set_attr "length" "5,5,6")])
7121 (define_insn "lshrsi3"
7122 [(set (match_operand:SI 0 "register_operand" "=r")
7123 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7124 (match_operand:SI 2 "arith_operand" "rI")))]
7127 if (GET_CODE (operands[2]) == CONST_INT)
7128 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7129 return "srl\t%1, %2, %0";
7131 [(set_attr "type" "shift")])
7133 ;; This handles the case where
7134 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
7135 ;; but combiner "simplifies" it for us.
7136 (define_insn "*lshrsi3_extend"
7137 [(set (match_operand:DI 0 "register_operand" "=r")
7138 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7139 (match_operand:SI 2 "arith_operand" "r")) 0)
7140 (match_operand 3 "" "")))]
7142 && ((GET_CODE (operands[3]) == CONST_DOUBLE
7143 && CONST_DOUBLE_HIGH (operands[3]) == 0
7144 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
7145 || (HOST_BITS_PER_WIDE_INT >= 64
7146 && GET_CODE (operands[3]) == CONST_INT
7147 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
7149 [(set_attr "type" "shift")])
7151 ;; This handles the case where
7152 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
7153 ;; but combiner "simplifies" it for us.
7154 (define_insn "*lshrsi3_extend2"
7155 [(set (match_operand:DI 0 "register_operand" "=r")
7156 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7157 (match_operand 2 "small_int_or_double" "n")
7160 && ((GET_CODE (operands[2]) == CONST_INT
7161 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7162 || (GET_CODE (operands[2]) == CONST_DOUBLE
7163 && CONST_DOUBLE_HIGH (operands[2]) == 0
7164 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7166 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
7168 return "srl\t%1, %2, %0";
7170 [(set_attr "type" "shift")])
7172 (define_expand "lshrdi3"
7173 [(set (match_operand:DI 0 "register_operand" "=r")
7174 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7175 (match_operand:SI 2 "arith_operand" "rI")))]
7176 "TARGET_ARCH64 || TARGET_V8PLUS"
7178 if (! TARGET_ARCH64)
7180 if (GET_CODE (operands[2]) == CONST_INT)
7182 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
7187 (define_insn "*lshrdi3_sp64"
7188 [(set (match_operand:DI 0 "register_operand" "=r")
7189 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7190 (match_operand:SI 2 "arith_operand" "rI")))]
7193 if (GET_CODE (operands[2]) == CONST_INT)
7194 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7195 return "srlx\t%1, %2, %0";
7197 [(set_attr "type" "shift")])
7200 (define_insn "lshrdi3_v8plus"
7201 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7202 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7203 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7204 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7206 "* return output_v8plus_shift (operands, insn, \"srlx\");"
7207 [(set_attr "type" "multi")
7208 (set_attr "length" "5,5,6")])
7211 [(set (match_operand:SI 0 "register_operand" "=r")
7212 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7214 (match_operand:SI 2 "small_int_or_double" "n")))]
7216 && ((GET_CODE (operands[2]) == CONST_INT
7217 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7218 || (GET_CODE (operands[2]) == CONST_DOUBLE
7219 && !CONST_DOUBLE_HIGH (operands[2])
7220 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7222 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7224 return "srax\t%1, %2, %0";
7226 [(set_attr "type" "shift")])
7229 [(set (match_operand:SI 0 "register_operand" "=r")
7230 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7232 (match_operand:SI 2 "small_int_or_double" "n")))]
7234 && ((GET_CODE (operands[2]) == CONST_INT
7235 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7236 || (GET_CODE (operands[2]) == CONST_DOUBLE
7237 && !CONST_DOUBLE_HIGH (operands[2])
7238 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7240 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7242 return "srlx\t%1, %2, %0";
7244 [(set_attr "type" "shift")])
7247 [(set (match_operand:SI 0 "register_operand" "=r")
7248 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7249 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7250 (match_operand:SI 3 "small_int_or_double" "n")))]
7252 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7253 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7254 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7255 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7257 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7259 return "srax\t%1, %2, %0";
7261 [(set_attr "type" "shift")])
7264 [(set (match_operand:SI 0 "register_operand" "=r")
7265 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7266 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7267 (match_operand:SI 3 "small_int_or_double" "n")))]
7269 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7270 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7271 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7272 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7274 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7276 return "srlx\t%1, %2, %0";
7278 [(set_attr "type" "shift")])
7280 ;; Unconditional and other jump instructions
7282 [(set (pc) (label_ref (match_operand 0 "" "")))]
7284 "* return output_ubranch (operands[0], 0, insn);"
7285 [(set_attr "type" "uncond_branch")])
7287 (define_expand "tablejump"
7288 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
7289 (use (label_ref (match_operand 1 "" "")))])]
7292 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
7295 /* In pic mode, our address differences are against the base of the
7296 table. Add that base value back in; CSE ought to be able to combine
7297 the two address loads. */
7301 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
7303 if (CASE_VECTOR_MODE != Pmode)
7304 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
7305 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
7306 operands[0] = memory_address (Pmode, tmp);
7310 (define_insn "*tablejump_sp32"
7311 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
7312 (use (label_ref (match_operand 1 "" "")))]
7315 [(set_attr "type" "uncond_branch")])
7317 (define_insn "*tablejump_sp64"
7318 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
7319 (use (label_ref (match_operand 1 "" "")))]
7322 [(set_attr "type" "uncond_branch")])
7324 ;;- jump to subroutine
7325 (define_expand "call"
7326 ;; Note that this expression is not used for generating RTL.
7327 ;; All the RTL is generated explicitly below.
7328 [(call (match_operand 0 "call_operand" "")
7329 (match_operand 3 "" "i"))]
7330 ;; operands[2] is next_arg_register
7331 ;; operands[3] is struct_value_size_rtx.
7336 if (GET_MODE (operands[0]) != FUNCTION_MODE)
7339 if (GET_CODE (operands[3]) != CONST_INT)
7342 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
7344 /* This is really a PIC sequence. We want to represent
7345 it as a funny jump so its delay slots can be filled.
7347 ??? But if this really *is* a CALL, will not it clobber the
7348 call-clobbered registers? We lose this if it is a JUMP_INSN.
7349 Why cannot we have delay slots filled if it were a CALL? */
7351 /* We accept negative sizes for untyped calls. */
7352 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7357 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7359 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7365 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7366 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7370 fn_rtx = operands[0];
7372 /* We accept negative sizes for untyped calls. */
7373 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7377 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
7379 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7384 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
7385 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7392 ;; We can't use the same pattern for these two insns, because then registers
7393 ;; in the address may not be properly reloaded.
7395 (define_insn "*call_address_sp32"
7396 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7397 (match_operand 1 "" ""))
7398 (clobber (reg:SI 15))]
7399 ;;- Do not use operand 1 for most machines.
7402 [(set_attr "type" "call")])
7404 (define_insn "*call_symbolic_sp32"
7405 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7406 (match_operand 1 "" ""))
7407 (clobber (reg:SI 15))]
7408 ;;- Do not use operand 1 for most machines.
7411 [(set_attr "type" "call")])
7413 (define_insn "*call_address_sp64"
7414 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
7415 (match_operand 1 "" ""))
7416 (clobber (reg:DI 15))]
7417 ;;- Do not use operand 1 for most machines.
7420 [(set_attr "type" "call")])
7422 (define_insn "*call_symbolic_sp64"
7423 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7424 (match_operand 1 "" ""))
7425 (clobber (reg:DI 15))]
7426 ;;- Do not use operand 1 for most machines.
7429 [(set_attr "type" "call")])
7431 ;; This is a call that wants a structure value.
7432 ;; There is no such critter for v9 (??? we may need one anyway).
7433 (define_insn "*call_address_struct_value_sp32"
7434 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7435 (match_operand 1 "" ""))
7436 (match_operand 2 "immediate_operand" "")
7437 (clobber (reg:SI 15))]
7438 ;;- Do not use operand 1 for most machines.
7439 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
7440 "call\t%a0, %1\n\t nop\n\tunimp\t%2"
7441 [(set_attr "type" "call_no_delay_slot")
7442 (set_attr "length" "3")])
7444 ;; This is a call that wants a structure value.
7445 ;; There is no such critter for v9 (??? we may need one anyway).
7446 (define_insn "*call_symbolic_struct_value_sp32"
7447 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7448 (match_operand 1 "" ""))
7449 (match_operand 2 "immediate_operand" "")
7450 (clobber (reg:SI 15))]
7451 ;;- Do not use operand 1 for most machines.
7452 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
7453 "call\t%a0, %1\n\t nop\n\tunimp\t%2"
7454 [(set_attr "type" "call_no_delay_slot")
7455 (set_attr "length" "3")])
7457 ;; This is a call that may want a structure value. This is used for
7459 (define_insn "*call_address_untyped_struct_value_sp32"
7460 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7461 (match_operand 1 "" ""))
7462 (match_operand 2 "immediate_operand" "")
7463 (clobber (reg:SI 15))]
7464 ;;- Do not use operand 1 for most machines.
7465 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7466 "call\t%a0, %1\n\t nop\n\tnop"
7467 [(set_attr "type" "call_no_delay_slot")
7468 (set_attr "length" "3")])
7470 ;; This is a call that may want a structure value. This is used for
7472 (define_insn "*call_symbolic_untyped_struct_value_sp32"
7473 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7474 (match_operand 1 "" ""))
7475 (match_operand 2 "immediate_operand" "")
7476 (clobber (reg:SI 15))]
7477 ;;- Do not use operand 1 for most machines.
7478 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7479 "call\t%a0, %1\n\t nop\n\tnop"
7480 [(set_attr "type" "call_no_delay_slot")
7481 (set_attr "length" "3")])
7483 (define_expand "call_value"
7484 ;; Note that this expression is not used for generating RTL.
7485 ;; All the RTL is generated explicitly below.
7486 [(set (match_operand 0 "register_operand" "=rf")
7487 (call (match_operand 1 "" "")
7488 (match_operand 4 "" "")))]
7489 ;; operand 2 is stack_size_rtx
7490 ;; operand 3 is next_arg_register
7496 if (GET_MODE (operands[1]) != FUNCTION_MODE)
7499 fn_rtx = operands[1];
7502 gen_rtx_SET (VOIDmode, operands[0],
7503 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
7504 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
7506 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7511 (define_insn "*call_value_address_sp32"
7512 [(set (match_operand 0 "" "=rf")
7513 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
7514 (match_operand 2 "" "")))
7515 (clobber (reg:SI 15))]
7516 ;;- Do not use operand 2 for most machines.
7519 [(set_attr "type" "call")])
7521 (define_insn "*call_value_symbolic_sp32"
7522 [(set (match_operand 0 "" "=rf")
7523 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7524 (match_operand 2 "" "")))
7525 (clobber (reg:SI 15))]
7526 ;;- Do not use operand 2 for most machines.
7529 [(set_attr "type" "call")])
7531 (define_insn "*call_value_address_sp64"
7532 [(set (match_operand 0 "" "")
7533 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
7534 (match_operand 2 "" "")))
7535 (clobber (reg:DI 15))]
7536 ;;- Do not use operand 2 for most machines.
7539 [(set_attr "type" "call")])
7541 (define_insn "*call_value_symbolic_sp64"
7542 [(set (match_operand 0 "" "")
7543 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7544 (match_operand 2 "" "")))
7545 (clobber (reg:DI 15))]
7546 ;;- Do not use operand 2 for most machines.
7549 [(set_attr "type" "call")])
7551 (define_expand "untyped_call"
7552 [(parallel [(call (match_operand 0 "" "")
7554 (match_operand 1 "" "")
7555 (match_operand 2 "" "")])]
7560 /* Pass constm1 to indicate that it may expect a structure value, but
7561 we don't know what size it is. */
7562 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
7564 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7566 rtx set = XVECEXP (operands[2], 0, i);
7567 emit_move_insn (SET_DEST (set), SET_SRC (set));
7570 /* The optimizer does not know that the call sets the function value
7571 registers we stored in the result block. We avoid problems by
7572 claiming that all hard registers are used and clobbered at this
7574 emit_insn (gen_blockage ());
7580 (define_expand "sibcall"
7581 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
7586 (define_insn "*sibcall_symbolic_sp32"
7587 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7588 (match_operand 1 "" ""))
7591 "* return output_sibcall(insn, operands[0]);"
7592 [(set_attr "type" "sibcall")])
7594 (define_insn "*sibcall_symbolic_sp64"
7595 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7596 (match_operand 1 "" ""))
7599 "* return output_sibcall(insn, operands[0]);"
7600 [(set_attr "type" "sibcall")])
7602 (define_expand "sibcall_value"
7603 [(parallel [(set (match_operand 0 "register_operand" "=rf")
7604 (call (match_operand 1 "" "") (const_int 0)))
7609 (define_insn "*sibcall_value_symbolic_sp32"
7610 [(set (match_operand 0 "" "=rf")
7611 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7612 (match_operand 2 "" "")))
7615 "* return output_sibcall(insn, operands[1]);"
7616 [(set_attr "type" "sibcall")])
7618 (define_insn "*sibcall_value_symbolic_sp64"
7619 [(set (match_operand 0 "" "")
7620 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7621 (match_operand 2 "" "")))
7624 "* return output_sibcall(insn, operands[1]);"
7625 [(set_attr "type" "sibcall")])
7627 (define_expand "sibcall_epilogue"
7631 sparc_expand_epilogue ();
7635 (define_expand "prologue"
7639 sparc_expand_prologue ();
7643 (define_expand "save_register_window"
7644 [(use (match_operand 0 "arith_operand" ""))]
7650 gen_rtx_SET (VOIDmode,
7652 gen_rtx_PLUS (Pmode,
7653 hard_frame_pointer_rtx,
7655 gen_rtx_UNSPEC_VOLATILE (VOIDmode,
7656 gen_rtvec (1, const0_rtx),
7659 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7663 (define_insn "*save_register_windowsi"
7664 [(set (reg:SI 14) (plus:SI (reg:SI 30)
7665 (match_operand:SI 0 "arith_operand" "rI")))
7666 (unspec_volatile [(const_int 0)] UNSPECV_SAVEW)]
7668 "save\t%%sp, %0, %%sp"
7669 [(set_attr "type" "savew")])
7671 (define_insn "*save_register_windowdi"
7672 [(set (reg:DI 14) (plus:DI (reg:DI 30)
7673 (match_operand:DI 0 "arith_operand" "rI")))
7674 (unspec_volatile [(const_int 0)] UNSPECV_SAVEW)]
7676 "save\t%%sp, %0, %%sp"
7677 [(set_attr "type" "savew")])
7679 (define_expand "epilogue"
7683 sparc_expand_epilogue ();
7686 (define_insn "*return_internal"
7689 "* return output_return (insn);"
7690 [(set_attr "type" "return")
7691 (set (attr "length")
7692 (cond [(eq_attr "leaf_function" "true")
7693 (if_then_else (eq_attr "empty_delay_slot" "true")
7696 (eq_attr "calls_eh_return" "true")
7697 (if_then_else (eq_attr "delayed_branch" "true")
7698 (if_then_else (eq_attr "isa" "v9")
7701 (if_then_else (eq_attr "isa" "v9")
7704 (eq_attr "empty_delay_slot" "true")
7705 (if_then_else (eq_attr "delayed_branch" "true")
7710 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7711 ;; all of memory. This blocks insns from being moved across this point.
7713 (define_insn "blockage"
7714 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7717 [(set_attr "length" "0")])
7719 ;; Prepare to return any type including a structure value.
7721 (define_expand "untyped_return"
7722 [(match_operand:BLK 0 "memory_operand" "")
7723 (match_operand 1 "" "")]
7726 rtx valreg1 = gen_rtx_REG (DImode, 24);
7727 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7728 rtx result = operands[0];
7730 if (! TARGET_ARCH64)
7732 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7734 rtx value = gen_reg_rtx (SImode);
7736 /* Fetch the instruction where we will return to and see if it's an unimp
7737 instruction (the most significant 10 bits will be zero). If so,
7738 update the return address to skip the unimp instruction. */
7739 emit_move_insn (value,
7740 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7741 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7742 emit_insn (gen_update_return (rtnreg, value));
7745 /* Reload the function value registers. */
7746 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7747 emit_move_insn (valreg2,
7748 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7750 /* Put USE insns before the return. */
7751 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7752 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7754 /* Construct the return. */
7755 expand_naked_return ();
7760 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
7761 ;; and parts of the compiler don't want to believe that the add is needed.
7763 (define_insn "update_return"
7764 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7765 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7768 if (flag_delayed_branch)
7769 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
7771 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
7773 [(set (attr "type") (const_string "multi"))
7774 (set (attr "length")
7775 (if_then_else (eq_attr "delayed_branch" "true")
7784 (define_expand "indirect_jump"
7785 [(set (pc) (match_operand 0 "address_operand" "p"))]
7789 (define_insn "*branch_sp32"
7790 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7793 [(set_attr "type" "uncond_branch")])
7795 (define_insn "*branch_sp64"
7796 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7799 [(set_attr "type" "uncond_branch")])
7801 (define_expand "nonlocal_goto"
7802 [(match_operand:SI 0 "general_operand" "")
7803 (match_operand:SI 1 "general_operand" "")
7804 (match_operand:SI 2 "general_operand" "")
7805 (match_operand:SI 3 "" "")]
7808 rtx lab = operands[1];
7809 rtx stack = operands[2];
7810 rtx fp = operands[3];
7813 /* Trap instruction to flush all the register windows. */
7814 emit_insn (gen_flush_register_windows ());
7816 /* Load the fp value for the containing fn into %fp. This is needed
7817 because STACK refers to %fp. Note that virtual register instantiation
7818 fails if the virtual %fp isn't set from a register. */
7819 if (GET_CODE (fp) != REG)
7820 fp = force_reg (Pmode, fp);
7821 emit_move_insn (virtual_stack_vars_rtx, fp);
7823 /* Find the containing function's current nonlocal goto handler,
7824 which will do any cleanups and then jump to the label. */
7825 labreg = gen_rtx_REG (Pmode, 8);
7826 emit_move_insn (labreg, lab);
7828 /* Restore %fp from stack pointer value for containing function.
7829 The restore insn that follows will move this to %sp,
7830 and reload the appropriate value into %fp. */
7831 emit_move_insn (hard_frame_pointer_rtx, stack);
7833 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7834 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7836 /* ??? The V9-specific version was disabled in rev 1.65. */
7837 emit_jump_insn (gen_goto_handler_and_restore (labreg));
7842 ;; Special trap insn to flush register windows.
7843 (define_insn "flush_register_windows"
7844 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7846 { return TARGET_V9 ? "flushw" : "ta\t3"; }
7847 [(set_attr "type" "flushw")])
7849 (define_insn "goto_handler_and_restore"
7850 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7851 "GET_MODE (operands[0]) == Pmode"
7853 if (flag_delayed_branch)
7854 return "jmp\t%0\n\t restore";
7856 return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
7858 [(set (attr "type") (const_string "multi"))
7859 (set (attr "length")
7860 (if_then_else (eq_attr "delayed_branch" "true")
7864 ;; For __builtin_setjmp we need to flush register windows iff the function
7865 ;; calls alloca as well, because otherwise the register window might be
7866 ;; saved after %sp adjustment and thus setjmp would crash
7867 (define_expand "builtin_setjmp_setup"
7868 [(match_operand 0 "register_operand" "r")]
7871 emit_insn (gen_do_builtin_setjmp_setup ());
7875 (define_insn "do_builtin_setjmp_setup"
7876 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7879 if (! current_function_calls_alloca)
7883 fputs ("\tflushw\n", asm_out_file);
7885 fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7886 TARGET_ARCH64 ? 'x' : 'w',
7887 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7888 fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7889 TARGET_ARCH64 ? 'x' : 'w',
7890 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7891 fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7892 TARGET_ARCH64 ? 'x' : 'w',
7893 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7896 [(set_attr "type" "multi")
7897 (set (attr "length")
7898 (cond [(eq_attr "calls_alloca" "false")
7900 (eq_attr "isa" "!v9")
7902 (eq_attr "pic" "true")
7903 (const_int 4)] (const_int 3)))])
7905 ;; Pattern for use after a setjmp to store FP and the return register
7906 ;; into the stack area.
7908 (define_expand "setjmp"
7913 emit_insn (gen_setjmp_64 ());
7915 emit_insn (gen_setjmp_32 ());
7919 (define_expand "setjmp_32"
7920 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
7921 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
7923 { operands[0] = frame_pointer_rtx; })
7925 (define_expand "setjmp_64"
7926 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
7927 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
7929 { operands[0] = frame_pointer_rtx; })
7931 ;; Special pattern for the FLUSH instruction.
7933 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7934 ; of the define_insn otherwise missing a mode. We make "flush", aka
7935 ; gen_flush, the default one since sparc_initialize_trampoline uses
7936 ; it on SImode mem values.
7938 (define_insn "flush"
7939 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7941 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7942 [(set_attr "type" "iflush")])
7944 (define_insn "flushdi"
7945 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7947 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7948 [(set_attr "type" "iflush")])
7953 ;; The scan instruction searches from the most significant bit while ffs
7954 ;; searches from the least significant bit. The bit index and treatment of
7955 ;; zero also differ. It takes at least 7 instructions to get the proper
7956 ;; result. Here is an obvious 8 instruction sequence.
7959 (define_insn "ffssi2"
7960 [(set (match_operand:SI 0 "register_operand" "=&r")
7961 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7962 (clobber (match_scratch:SI 2 "=&r"))]
7963 "TARGET_SPARCLITE || TARGET_SPARCLET"
7965 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";
7967 [(set_attr "type" "multi")
7968 (set_attr "length" "8")])
7970 ;; ??? This should be a define expand, so that the extra instruction have
7971 ;; a chance of being optimized away.
7973 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
7974 ;; does, but no one uses that and we don't have a switch for it.
7976 ;(define_insn "ffsdi2"
7977 ; [(set (match_operand:DI 0 "register_operand" "=&r")
7978 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
7979 ; (clobber (match_scratch:DI 2 "=&r"))]
7981 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
7982 ; [(set_attr "type" "multi")
7983 ; (set_attr "length" "4")])
7987 ;; Peepholes go at the end.
7989 ;; Optimize consecutive loads or stores into ldd and std when possible.
7990 ;; The conditions in which we do this are very restricted and are
7991 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
7994 [(set (match_operand:SI 0 "memory_operand" "")
7996 (set (match_operand:SI 1 "memory_operand" "")
7999 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
8002 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
8005 [(set (match_operand:SI 0 "memory_operand" "")
8007 (set (match_operand:SI 1 "memory_operand" "")
8010 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
8013 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
8016 [(set (match_operand:SI 0 "register_operand" "")
8017 (match_operand:SI 1 "memory_operand" ""))
8018 (set (match_operand:SI 2 "register_operand" "")
8019 (match_operand:SI 3 "memory_operand" ""))]
8020 "registers_ok_for_ldd_peep (operands[0], operands[2])
8021 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8024 "operands[1] = widen_memory_access (operands[1], DImode, 0);
8025 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
8028 [(set (match_operand:SI 0 "memory_operand" "")
8029 (match_operand:SI 1 "register_operand" ""))
8030 (set (match_operand:SI 2 "memory_operand" "")
8031 (match_operand:SI 3 "register_operand" ""))]
8032 "registers_ok_for_ldd_peep (operands[1], operands[3])
8033 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8036 "operands[0] = widen_memory_access (operands[0], DImode, 0);
8037 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
8040 [(set (match_operand:SF 0 "register_operand" "")
8041 (match_operand:SF 1 "memory_operand" ""))
8042 (set (match_operand:SF 2 "register_operand" "")
8043 (match_operand:SF 3 "memory_operand" ""))]
8044 "registers_ok_for_ldd_peep (operands[0], operands[2])
8045 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8048 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
8049 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
8052 [(set (match_operand:SF 0 "memory_operand" "")
8053 (match_operand:SF 1 "register_operand" ""))
8054 (set (match_operand:SF 2 "memory_operand" "")
8055 (match_operand:SF 3 "register_operand" ""))]
8056 "registers_ok_for_ldd_peep (operands[1], operands[3])
8057 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8060 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
8061 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
8064 [(set (match_operand:SI 0 "register_operand" "")
8065 (match_operand:SI 1 "memory_operand" ""))
8066 (set (match_operand:SI 2 "register_operand" "")
8067 (match_operand:SI 3 "memory_operand" ""))]
8068 "registers_ok_for_ldd_peep (operands[2], operands[0])
8069 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8072 "operands[3] = widen_memory_access (operands[3], DImode, 0);
8073 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
8076 [(set (match_operand:SI 0 "memory_operand" "")
8077 (match_operand:SI 1 "register_operand" ""))
8078 (set (match_operand:SI 2 "memory_operand" "")
8079 (match_operand:SI 3 "register_operand" ""))]
8080 "registers_ok_for_ldd_peep (operands[3], operands[1])
8081 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8084 "operands[2] = widen_memory_access (operands[2], DImode, 0);
8085 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
8089 [(set (match_operand:SF 0 "register_operand" "")
8090 (match_operand:SF 1 "memory_operand" ""))
8091 (set (match_operand:SF 2 "register_operand" "")
8092 (match_operand:SF 3 "memory_operand" ""))]
8093 "registers_ok_for_ldd_peep (operands[2], operands[0])
8094 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8097 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
8098 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
8101 [(set (match_operand:SF 0 "memory_operand" "")
8102 (match_operand:SF 1 "register_operand" ""))
8103 (set (match_operand:SF 2 "memory_operand" "")
8104 (match_operand:SF 3 "register_operand" ""))]
8105 "registers_ok_for_ldd_peep (operands[3], operands[1])
8106 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8109 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
8110 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
8112 ;; Optimize the case of following a reg-reg move with a test
8113 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
8114 ;; This can result from a float to fix conversion.
8117 [(set (match_operand:SI 0 "register_operand" "")
8118 (match_operand:SI 1 "register_operand" ""))
8120 (compare:CC (match_operand:SI 2 "register_operand" "")
8122 "(rtx_equal_p (operands[2], operands[0])
8123 || rtx_equal_p (operands[2], operands[1]))
8124 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8125 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8126 [(parallel [(set (match_dup 0) (match_dup 1))
8128 (compare:CC (match_dup 1) (const_int 0)))])]
8132 [(set (match_operand:DI 0 "register_operand" "")
8133 (match_operand:DI 1 "register_operand" ""))
8135 (compare:CCX (match_operand:DI 2 "register_operand" "")
8138 && (rtx_equal_p (operands[2], operands[0])
8139 || rtx_equal_p (operands[2], operands[1]))
8140 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8141 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8142 [(parallel [(set (match_dup 0) (match_dup 1))
8144 (compare:CCX (match_dup 1) (const_int 0)))])]
8147 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
8148 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
8149 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
8151 (define_expand "prefetch"
8152 [(match_operand 0 "address_operand" "")
8153 (match_operand 1 "const_int_operand" "")
8154 (match_operand 2 "const_int_operand" "")]
8158 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
8160 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
8164 (define_insn "prefetch_64"
8165 [(prefetch (match_operand:DI 0 "address_operand" "p")
8166 (match_operand:DI 1 "const_int_operand" "n")
8167 (match_operand:DI 2 "const_int_operand" "n"))]
8170 static const char * const prefetch_instr[2][2] = {
8172 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8173 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8176 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8177 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8180 int read_or_write = INTVAL (operands[1]);
8181 int locality = INTVAL (operands[2]);
8183 if (read_or_write != 0 && read_or_write != 1)
8185 if (locality < 0 || locality > 3)
8187 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8189 [(set_attr "type" "load")])
8191 (define_insn "prefetch_32"
8192 [(prefetch (match_operand:SI 0 "address_operand" "p")
8193 (match_operand:SI 1 "const_int_operand" "n")
8194 (match_operand:SI 2 "const_int_operand" "n"))]
8197 static const char * const prefetch_instr[2][2] = {
8199 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8200 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8203 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8204 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8207 int read_or_write = INTVAL (operands[1]);
8208 int locality = INTVAL (operands[2]);
8210 if (read_or_write != 0 && read_or_write != 1)
8212 if (locality < 0 || locality > 3)
8214 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8216 [(set_attr "type" "load")])
8219 [(trap_if (const_int 1) (const_int 5))]
8222 [(set_attr "type" "trap")])
8224 (define_expand "conditional_trap"
8225 [(trap_if (match_operator 0 "noov_compare_op"
8226 [(match_dup 2) (match_dup 3)])
8227 (match_operand:SI 1 "arith_operand" ""))]
8229 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
8230 sparc_compare_op0, sparc_compare_op1);
8231 operands[3] = const0_rtx;")
8234 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
8235 (match_operand:SI 1 "arith_operand" "rM"))]
8238 [(set_attr "type" "trap")])
8241 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
8242 (match_operand:SI 1 "arith_operand" "rM"))]
8245 [(set_attr "type" "trap")])
8248 (define_insn "tgd_hi22"
8249 [(set (match_operand:SI 0 "register_operand" "=r")
8250 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
8253 "sethi\\t%%tgd_hi22(%a1), %0")
8255 (define_insn "tgd_lo10"
8256 [(set (match_operand:SI 0 "register_operand" "=r")
8257 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8258 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
8261 "add\\t%1, %%tgd_lo10(%a2), %0")
8263 (define_insn "tgd_add32"
8264 [(set (match_operand:SI 0 "register_operand" "=r")
8265 (plus:SI (match_operand:SI 1 "register_operand" "r")
8266 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8267 (match_operand 3 "tgd_symbolic_operand" "")]
8269 "TARGET_TLS && TARGET_ARCH32"
8270 "add\\t%1, %2, %0, %%tgd_add(%a3)")
8272 (define_insn "tgd_add64"
8273 [(set (match_operand:DI 0 "register_operand" "=r")
8274 (plus:DI (match_operand:DI 1 "register_operand" "r")
8275 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8276 (match_operand 3 "tgd_symbolic_operand" "")]
8278 "TARGET_TLS && TARGET_ARCH64"
8279 "add\\t%1, %2, %0, %%tgd_add(%a3)")
8281 (define_insn "tgd_call32"
8282 [(set (match_operand 0 "register_operand" "=r")
8283 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
8284 (match_operand 2 "tgd_symbolic_operand" "")]
8286 (match_operand 3 "" "")))
8287 (clobber (reg:SI 15))]
8288 "TARGET_TLS && TARGET_ARCH32"
8289 "call\t%a1, %%tgd_call(%a2)%#"
8290 [(set_attr "type" "call")])
8292 (define_insn "tgd_call64"
8293 [(set (match_operand 0 "register_operand" "=r")
8294 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
8295 (match_operand 2 "tgd_symbolic_operand" "")]
8297 (match_operand 3 "" "")))
8298 (clobber (reg:DI 15))]
8299 "TARGET_TLS && TARGET_ARCH64"
8300 "call\t%a1, %%tgd_call(%a2)%#"
8301 [(set_attr "type" "call")])
8303 (define_insn "tldm_hi22"
8304 [(set (match_operand:SI 0 "register_operand" "=r")
8305 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8307 "sethi\\t%%tldm_hi22(%&), %0")
8309 (define_insn "tldm_lo10"
8310 [(set (match_operand:SI 0 "register_operand" "=r")
8311 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8312 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8314 "add\\t%1, %%tldm_lo10(%&), %0")
8316 (define_insn "tldm_add32"
8317 [(set (match_operand:SI 0 "register_operand" "=r")
8318 (plus:SI (match_operand:SI 1 "register_operand" "r")
8319 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
8321 "TARGET_TLS && TARGET_ARCH32"
8322 "add\\t%1, %2, %0, %%tldm_add(%&)")
8324 (define_insn "tldm_add64"
8325 [(set (match_operand:DI 0 "register_operand" "=r")
8326 (plus:DI (match_operand:DI 1 "register_operand" "r")
8327 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
8329 "TARGET_TLS && TARGET_ARCH64"
8330 "add\\t%1, %2, %0, %%tldm_add(%&)")
8332 (define_insn "tldm_call32"
8333 [(set (match_operand 0 "register_operand" "=r")
8334 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
8336 (match_operand 2 "" "")))
8337 (clobber (reg:SI 15))]
8338 "TARGET_TLS && TARGET_ARCH32"
8339 "call\t%a1, %%tldm_call(%&)%#"
8340 [(set_attr "type" "call")])
8342 (define_insn "tldm_call64"
8343 [(set (match_operand 0 "register_operand" "=r")
8344 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
8346 (match_operand 2 "" "")))
8347 (clobber (reg:DI 15))]
8348 "TARGET_TLS && TARGET_ARCH64"
8349 "call\t%a1, %%tldm_call(%&)%#"
8350 [(set_attr "type" "call")])
8352 (define_insn "tldo_hix22"
8353 [(set (match_operand:SI 0 "register_operand" "=r")
8354 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
8357 "sethi\\t%%tldo_hix22(%a1), %0")
8359 (define_insn "tldo_lox10"
8360 [(set (match_operand:SI 0 "register_operand" "=r")
8361 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8362 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
8365 "xor\\t%1, %%tldo_lox10(%a2), %0")
8367 (define_insn "tldo_add32"
8368 [(set (match_operand:SI 0 "register_operand" "=r")
8369 (plus:SI (match_operand:SI 1 "register_operand" "r")
8370 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8371 (match_operand 3 "tld_symbolic_operand" "")]
8373 "TARGET_TLS && TARGET_ARCH32"
8374 "add\\t%1, %2, %0, %%tldo_add(%a3)")
8376 (define_insn "tldo_add64"
8377 [(set (match_operand:DI 0 "register_operand" "=r")
8378 (plus:DI (match_operand:DI 1 "register_operand" "r")
8379 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8380 (match_operand 3 "tld_symbolic_operand" "")]
8382 "TARGET_TLS && TARGET_ARCH64"
8383 "add\\t%1, %2, %0, %%tldo_add(%a3)")
8385 (define_insn "tie_hi22"
8386 [(set (match_operand:SI 0 "register_operand" "=r")
8387 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
8390 "sethi\\t%%tie_hi22(%a1), %0")
8392 (define_insn "tie_lo10"
8393 [(set (match_operand:SI 0 "register_operand" "=r")
8394 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8395 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
8398 "add\\t%1, %%tie_lo10(%a2), %0")
8400 (define_insn "tie_ld32"
8401 [(set (match_operand:SI 0 "register_operand" "=r")
8402 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
8403 (match_operand:SI 2 "register_operand" "r")
8404 (match_operand 3 "tie_symbolic_operand" "")]
8406 "TARGET_TLS && TARGET_ARCH32"
8407 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
8408 [(set_attr "type" "load")])
8410 (define_insn "tie_ld64"
8411 [(set (match_operand:DI 0 "register_operand" "=r")
8412 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
8413 (match_operand:SI 2 "register_operand" "r")
8414 (match_operand 3 "tie_symbolic_operand" "")]
8416 "TARGET_TLS && TARGET_ARCH64"
8417 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
8418 [(set_attr "type" "load")])
8420 (define_insn "tie_add32"
8421 [(set (match_operand:SI 0 "register_operand" "=r")
8422 (plus:SI (match_operand:SI 1 "register_operand" "r")
8423 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8424 (match_operand 3 "tie_symbolic_operand" "")]
8426 "TARGET_SUN_TLS && TARGET_ARCH32"
8427 "add\\t%1, %2, %0, %%tie_add(%a3)")
8429 (define_insn "tie_add64"
8430 [(set (match_operand:DI 0 "register_operand" "=r")
8431 (plus:DI (match_operand:DI 1 "register_operand" "r")
8432 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
8433 (match_operand 3 "tie_symbolic_operand" "")]
8435 "TARGET_SUN_TLS && TARGET_ARCH64"
8436 "add\\t%1, %2, %0, %%tie_add(%a3)")
8438 (define_insn "tle_hix22_sp32"
8439 [(set (match_operand:SI 0 "register_operand" "=r")
8440 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
8442 "TARGET_TLS && TARGET_ARCH32"
8443 "sethi\\t%%tle_hix22(%a1), %0")
8445 (define_insn "tle_lox10_sp32"
8446 [(set (match_operand:SI 0 "register_operand" "=r")
8447 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8448 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
8450 "TARGET_TLS && TARGET_ARCH32"
8451 "xor\\t%1, %%tle_lox10(%a2), %0")
8453 (define_insn "tle_hix22_sp64"
8454 [(set (match_operand:DI 0 "register_operand" "=r")
8455 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
8457 "TARGET_TLS && TARGET_ARCH64"
8458 "sethi\\t%%tle_hix22(%a1), %0")
8460 (define_insn "tle_lox10_sp64"
8461 [(set (match_operand:DI 0 "register_operand" "=r")
8462 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
8463 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
8465 "TARGET_TLS && TARGET_ARCH64"
8466 "xor\\t%1, %%tle_lox10(%a2), %0")
8468 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
8469 (define_insn "*tldo_ldub_sp32"
8470 [(set (match_operand:QI 0 "register_operand" "=r")
8471 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8472 (match_operand 3 "tld_symbolic_operand" "")]
8474 (match_operand:SI 1 "register_operand" "r"))))]
8475 "TARGET_TLS && TARGET_ARCH32"
8476 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8477 [(set_attr "type" "load")
8478 (set_attr "us3load_type" "3cycle")])
8480 (define_insn "*tldo_ldub1_sp32"
8481 [(set (match_operand:HI 0 "register_operand" "=r")
8482 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8483 (match_operand 3 "tld_symbolic_operand" "")]
8485 (match_operand:SI 1 "register_operand" "r")))))]
8486 "TARGET_TLS && TARGET_ARCH32"
8487 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8488 [(set_attr "type" "load")
8489 (set_attr "us3load_type" "3cycle")])
8491 (define_insn "*tldo_ldub2_sp32"
8492 [(set (match_operand:SI 0 "register_operand" "=r")
8493 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8494 (match_operand 3 "tld_symbolic_operand" "")]
8496 (match_operand:SI 1 "register_operand" "r")))))]
8497 "TARGET_TLS && TARGET_ARCH32"
8498 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8499 [(set_attr "type" "load")
8500 (set_attr "us3load_type" "3cycle")])
8502 (define_insn "*tldo_ldsb1_sp32"
8503 [(set (match_operand:HI 0 "register_operand" "=r")
8504 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8505 (match_operand 3 "tld_symbolic_operand" "")]
8507 (match_operand:SI 1 "register_operand" "r")))))]
8508 "TARGET_TLS && TARGET_ARCH32"
8509 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8510 [(set_attr "type" "sload")
8511 (set_attr "us3load_type" "3cycle")])
8513 (define_insn "*tldo_ldsb2_sp32"
8514 [(set (match_operand:SI 0 "register_operand" "=r")
8515 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8516 (match_operand 3 "tld_symbolic_operand" "")]
8518 (match_operand:SI 1 "register_operand" "r")))))]
8519 "TARGET_TLS && TARGET_ARCH32"
8520 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8521 [(set_attr "type" "sload")
8522 (set_attr "us3load_type" "3cycle")])
8524 (define_insn "*tldo_ldub_sp64"
8525 [(set (match_operand:QI 0 "register_operand" "=r")
8526 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8527 (match_operand 3 "tld_symbolic_operand" "")]
8529 (match_operand:DI 1 "register_operand" "r"))))]
8530 "TARGET_TLS && TARGET_ARCH64"
8531 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8532 [(set_attr "type" "load")
8533 (set_attr "us3load_type" "3cycle")])
8535 (define_insn "*tldo_ldub1_sp64"
8536 [(set (match_operand:HI 0 "register_operand" "=r")
8537 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8538 (match_operand 3 "tld_symbolic_operand" "")]
8540 (match_operand:DI 1 "register_operand" "r")))))]
8541 "TARGET_TLS && TARGET_ARCH64"
8542 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8543 [(set_attr "type" "load")
8544 (set_attr "us3load_type" "3cycle")])
8546 (define_insn "*tldo_ldub2_sp64"
8547 [(set (match_operand:SI 0 "register_operand" "=r")
8548 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8549 (match_operand 3 "tld_symbolic_operand" "")]
8551 (match_operand:DI 1 "register_operand" "r")))))]
8552 "TARGET_TLS && TARGET_ARCH64"
8553 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8554 [(set_attr "type" "load")
8555 (set_attr "us3load_type" "3cycle")])
8557 (define_insn "*tldo_ldub3_sp64"
8558 [(set (match_operand:DI 0 "register_operand" "=r")
8559 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8560 (match_operand 3 "tld_symbolic_operand" "")]
8562 (match_operand:DI 1 "register_operand" "r")))))]
8563 "TARGET_TLS && TARGET_ARCH64"
8564 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8565 [(set_attr "type" "load")
8566 (set_attr "us3load_type" "3cycle")])
8568 (define_insn "*tldo_ldsb1_sp64"
8569 [(set (match_operand:HI 0 "register_operand" "=r")
8570 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8571 (match_operand 3 "tld_symbolic_operand" "")]
8573 (match_operand:DI 1 "register_operand" "r")))))]
8574 "TARGET_TLS && TARGET_ARCH64"
8575 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8576 [(set_attr "type" "sload")
8577 (set_attr "us3load_type" "3cycle")])
8579 (define_insn "*tldo_ldsb2_sp64"
8580 [(set (match_operand:SI 0 "register_operand" "=r")
8581 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8582 (match_operand 3 "tld_symbolic_operand" "")]
8584 (match_operand:DI 1 "register_operand" "r")))))]
8585 "TARGET_TLS && TARGET_ARCH64"
8586 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8587 [(set_attr "type" "sload")
8588 (set_attr "us3load_type" "3cycle")])
8590 (define_insn "*tldo_ldsb3_sp64"
8591 [(set (match_operand:DI 0 "register_operand" "=r")
8592 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8593 (match_operand 3 "tld_symbolic_operand" "")]
8595 (match_operand:DI 1 "register_operand" "r")))))]
8596 "TARGET_TLS && TARGET_ARCH64"
8597 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8598 [(set_attr "type" "sload")
8599 (set_attr "us3load_type" "3cycle")])
8601 (define_insn "*tldo_lduh_sp32"
8602 [(set (match_operand:HI 0 "register_operand" "=r")
8603 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8604 (match_operand 3 "tld_symbolic_operand" "")]
8606 (match_operand:SI 1 "register_operand" "r"))))]
8607 "TARGET_TLS && TARGET_ARCH32"
8608 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8609 [(set_attr "type" "load")
8610 (set_attr "us3load_type" "3cycle")])
8612 (define_insn "*tldo_lduh1_sp32"
8613 [(set (match_operand:SI 0 "register_operand" "=r")
8614 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8615 (match_operand 3 "tld_symbolic_operand" "")]
8617 (match_operand:SI 1 "register_operand" "r")))))]
8618 "TARGET_TLS && TARGET_ARCH32"
8619 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8620 [(set_attr "type" "load")
8621 (set_attr "us3load_type" "3cycle")])
8623 (define_insn "*tldo_ldsh1_sp32"
8624 [(set (match_operand:SI 0 "register_operand" "=r")
8625 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8626 (match_operand 3 "tld_symbolic_operand" "")]
8628 (match_operand:SI 1 "register_operand" "r")))))]
8629 "TARGET_TLS && TARGET_ARCH32"
8630 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8631 [(set_attr "type" "sload")
8632 (set_attr "us3load_type" "3cycle")])
8634 (define_insn "*tldo_lduh_sp64"
8635 [(set (match_operand:HI 0 "register_operand" "=r")
8636 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8637 (match_operand 3 "tld_symbolic_operand" "")]
8639 (match_operand:DI 1 "register_operand" "r"))))]
8640 "TARGET_TLS && TARGET_ARCH64"
8641 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8642 [(set_attr "type" "load")
8643 (set_attr "us3load_type" "3cycle")])
8645 (define_insn "*tldo_lduh1_sp64"
8646 [(set (match_operand:SI 0 "register_operand" "=r")
8647 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8648 (match_operand 3 "tld_symbolic_operand" "")]
8650 (match_operand:DI 1 "register_operand" "r")))))]
8651 "TARGET_TLS && TARGET_ARCH64"
8652 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8653 [(set_attr "type" "load")
8654 (set_attr "us3load_type" "3cycle")])
8656 (define_insn "*tldo_lduh2_sp64"
8657 [(set (match_operand:DI 0 "register_operand" "=r")
8658 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8659 (match_operand 3 "tld_symbolic_operand" "")]
8661 (match_operand:DI 1 "register_operand" "r")))))]
8662 "TARGET_TLS && TARGET_ARCH64"
8663 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8664 [(set_attr "type" "load")
8665 (set_attr "us3load_type" "3cycle")])
8667 (define_insn "*tldo_ldsh1_sp64"
8668 [(set (match_operand:SI 0 "register_operand" "=r")
8669 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8670 (match_operand 3 "tld_symbolic_operand" "")]
8672 (match_operand:DI 1 "register_operand" "r")))))]
8673 "TARGET_TLS && TARGET_ARCH64"
8674 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8675 [(set_attr "type" "sload")
8676 (set_attr "us3load_type" "3cycle")])
8678 (define_insn "*tldo_ldsh2_sp64"
8679 [(set (match_operand:DI 0 "register_operand" "=r")
8680 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8681 (match_operand 3 "tld_symbolic_operand" "")]
8683 (match_operand:DI 1 "register_operand" "r")))))]
8684 "TARGET_TLS && TARGET_ARCH64"
8685 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8686 [(set_attr "type" "sload")
8687 (set_attr "us3load_type" "3cycle")])
8689 (define_insn "*tldo_lduw_sp32"
8690 [(set (match_operand:SI 0 "register_operand" "=r")
8691 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8692 (match_operand 3 "tld_symbolic_operand" "")]
8694 (match_operand:SI 1 "register_operand" "r"))))]
8695 "TARGET_TLS && TARGET_ARCH32"
8696 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
8697 [(set_attr "type" "load")])
8699 (define_insn "*tldo_lduw_sp64"
8700 [(set (match_operand:SI 0 "register_operand" "=r")
8701 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8702 (match_operand 3 "tld_symbolic_operand" "")]
8704 (match_operand:DI 1 "register_operand" "r"))))]
8705 "TARGET_TLS && TARGET_ARCH64"
8706 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8707 [(set_attr "type" "load")])
8709 (define_insn "*tldo_lduw1_sp64"
8710 [(set (match_operand:DI 0 "register_operand" "=r")
8711 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8712 (match_operand 3 "tld_symbolic_operand" "")]
8714 (match_operand:DI 1 "register_operand" "r")))))]
8715 "TARGET_TLS && TARGET_ARCH64"
8716 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8717 [(set_attr "type" "load")])
8719 (define_insn "*tldo_ldsw1_sp64"
8720 [(set (match_operand:DI 0 "register_operand" "=r")
8721 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8722 (match_operand 3 "tld_symbolic_operand" "")]
8724 (match_operand:DI 1 "register_operand" "r")))))]
8725 "TARGET_TLS && TARGET_ARCH64"
8726 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
8727 [(set_attr "type" "sload")
8728 (set_attr "us3load_type" "3cycle")])
8730 (define_insn "*tldo_ldx_sp64"
8731 [(set (match_operand:DI 0 "register_operand" "=r")
8732 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8733 (match_operand 3 "tld_symbolic_operand" "")]
8735 (match_operand:DI 1 "register_operand" "r"))))]
8736 "TARGET_TLS && TARGET_ARCH64"
8737 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
8738 [(set_attr "type" "load")])
8740 (define_insn "*tldo_stb_sp32"
8741 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8742 (match_operand 3 "tld_symbolic_operand" "")]
8744 (match_operand:SI 1 "register_operand" "r")))
8745 (match_operand:QI 0 "register_operand" "=r"))]
8746 "TARGET_TLS && TARGET_ARCH32"
8747 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8748 [(set_attr "type" "store")])
8750 (define_insn "*tldo_stb_sp64"
8751 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8752 (match_operand 3 "tld_symbolic_operand" "")]
8754 (match_operand:DI 1 "register_operand" "r")))
8755 (match_operand:QI 0 "register_operand" "=r"))]
8756 "TARGET_TLS && TARGET_ARCH64"
8757 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8758 [(set_attr "type" "store")])
8760 (define_insn "*tldo_sth_sp32"
8761 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8762 (match_operand 3 "tld_symbolic_operand" "")]
8764 (match_operand:SI 1 "register_operand" "r")))
8765 (match_operand:HI 0 "register_operand" "=r"))]
8766 "TARGET_TLS && TARGET_ARCH32"
8767 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8768 [(set_attr "type" "store")])
8770 (define_insn "*tldo_sth_sp64"
8771 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8772 (match_operand 3 "tld_symbolic_operand" "")]
8774 (match_operand:DI 1 "register_operand" "r")))
8775 (match_operand:HI 0 "register_operand" "=r"))]
8776 "TARGET_TLS && TARGET_ARCH64"
8777 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8778 [(set_attr "type" "store")])
8780 (define_insn "*tldo_stw_sp32"
8781 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8782 (match_operand 3 "tld_symbolic_operand" "")]
8784 (match_operand:SI 1 "register_operand" "r")))
8785 (match_operand:SI 0 "register_operand" "=r"))]
8786 "TARGET_TLS && TARGET_ARCH32"
8787 "st\t%0, [%1 + %2], %%tldo_add(%3)"
8788 [(set_attr "type" "store")])
8790 (define_insn "*tldo_stw_sp64"
8791 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8792 (match_operand 3 "tld_symbolic_operand" "")]
8794 (match_operand:DI 1 "register_operand" "r")))
8795 (match_operand:SI 0 "register_operand" "=r"))]
8796 "TARGET_TLS && TARGET_ARCH64"
8797 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8798 [(set_attr "type" "store")])
8800 (define_insn "*tldo_stx_sp64"
8801 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8802 (match_operand 3 "tld_symbolic_operand" "")]
8804 (match_operand:DI 1 "register_operand" "r")))
8805 (match_operand:DI 0 "register_operand" "=r"))]
8806 "TARGET_TLS && TARGET_ARCH64"
8807 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8808 [(set_attr "type" "store")])