aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.8/gcc/config/sparc/sparc.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.8/gcc/config/sparc/sparc.md')
-rw-r--r--gcc-4.8/gcc/config/sparc/sparc.md427
1 files changed, 231 insertions, 196 deletions
diff --git a/gcc-4.8/gcc/config/sparc/sparc.md b/gcc-4.8/gcc/config/sparc/sparc.md
index b60af4333..f380a414f 100644
--- a/gcc-4.8/gcc/config/sparc/sparc.md
+++ b/gcc-4.8/gcc/config/sparc/sparc.md
@@ -206,7 +206,7 @@
;; 'f' for all DF/TFmode values, including those that are specific to the v8.
;; Attribute for cpu type.
-;; These must match the values for enum processor_type in sparc.h.
+;; These must match the values of the enum processor_type in sparc-opts.h.
(define_attr "cpu"
"v7,
cypress,
@@ -214,6 +214,7 @@
supersparc,
hypersparc,
leon,
+ leon3,
sparclite,
f930,
f934,
@@ -284,7 +285,8 @@
(const_string "none"))
(define_attr "pic" "false,true"
- (symbol_ref "(flag_pic != 0 ? PIC_TRUE : PIC_FALSE)"))
+ (symbol_ref "(flag_pic != 0
+ ? PIC_TRUE : PIC_FALSE)"))
(define_attr "calls_alloca" "false,true"
(symbol_ref "(cfun->calls_alloca != 0
@@ -306,6 +308,10 @@
(symbol_ref "(TARGET_FLAT != 0
? FLAT_TRUE : FLAT_FALSE)"))
+(define_attr "fix_ut699" "false,true"
+ (symbol_ref "(sparc_fix_ut699 != 0
+ ? FIX_UT699_TRUE : FIX_UT699_FALSE)"))
+
;; Length (in # of insns).
;; Beware that setting a length greater or equal to 3 for conditional branches
;; has a side-effect (see output_cbranch and output_v9branch).
@@ -412,6 +418,10 @@
(define_attr "fptype" "single,double"
(const_string "single"))
+;; FP precision specific to the UT699.
+(define_attr "fptype_ut699" "none,single"
+ (const_string "none"))
+
;; UltraSPARC-III integer load type.
(define_attr "us3load_type" "2cycle,3cycle"
(const_string "2cycle"))
@@ -420,32 +430,18 @@
[(set_attr "length" "2")
(set_attr "type" "multi")])
-;; Attributes for instruction and branch scheduling
-(define_attr "tls_call_delay" "false,true"
- (symbol_ref "(tls_call_delay (insn)
- ? TLS_CALL_DELAY_TRUE : TLS_CALL_DELAY_FALSE)"))
-
+;; Attributes for branch scheduling
(define_attr "in_call_delay" "false,true"
- (cond [(eq_attr "type" "uncond_branch,branch,cbcond,uncond_cbcond,call,sibcall,call_no_delay_slot,multi")
- (const_string "false")
- (eq_attr "type" "load,fpload,store,fpstore")
- (if_then_else (eq_attr "length" "1")
- (const_string "true")
- (const_string "false"))]
- (if_then_else (and (eq_attr "length" "1")
- (eq_attr "tls_call_delay" "true"))
- (const_string "true")
- (const_string "false"))))
-
-(define_attr "eligible_for_sibcall_delay" "false,true"
+ (symbol_ref "(eligible_for_call_delay (insn)
+ ? IN_CALL_DELAY_TRUE : IN_CALL_DELAY_FALSE)"))
+
+(define_attr "in_sibcall_delay" "false,true"
(symbol_ref "(eligible_for_sibcall_delay (insn)
- ? ELIGIBLE_FOR_SIBCALL_DELAY_TRUE
- : ELIGIBLE_FOR_SIBCALL_DELAY_FALSE)"))
+ ? IN_SIBCALL_DELAY_TRUE : IN_SIBCALL_DELAY_FALSE)"))
-(define_attr "eligible_for_return_delay" "false,true"
+(define_attr "in_return_delay" "false,true"
(symbol_ref "(eligible_for_return_delay (insn)
- ? ELIGIBLE_FOR_RETURN_DELAY_TRUE
- : ELIGIBLE_FOR_RETURN_DELAY_FALSE)"))
+ ? IN_RETURN_DELAY_TRUE : IN_RETURN_DELAY_FALSE)"))
;; ??? !v9: Should implement the notion of predelay slots for floating-point
;; branches. This would allow us to remove the nop always inserted before
@@ -460,39 +456,33 @@
;; because it prevents us from moving back the final store of inner loops.
(define_attr "in_branch_delay" "false,true"
- (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbcond,uncond_cbcond,call,sibcall,call_no_delay_slot,multi")
- (eq_attr "length" "1"))
- (const_string "true")
- (const_string "false")))
-
-(define_attr "in_uncond_branch_delay" "false,true"
- (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbcond,uncond_cbcond,call,sibcall,call_no_delay_slot,multi")
- (eq_attr "length" "1"))
- (const_string "true")
- (const_string "false")))
-
-(define_attr "in_annul_branch_delay" "false,true"
- (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbcond,uncond_cbcond,call,sibcall,call_no_delay_slot,multi")
- (eq_attr "length" "1"))
+ (cond [(eq_attr "type" "uncond_branch,branch,cbcond,uncond_cbcond,call,sibcall,call_no_delay_slot,multi")
+ (const_string "false")
+ (and (eq_attr "fix_ut699" "true") (eq_attr "type" "load,sload"))
+ (const_string "false")
+ (and (eq_attr "fix_ut699" "true")
+ (and (eq_attr "type" "fpload,fp,fpmove,fpmul,fpdivs,fpsqrts")
+ (ior (eq_attr "fptype" "single")
+ (eq_attr "fptype_ut699" "single"))))
+ (const_string "false")
+ (eq_attr "length" "1")
(const_string "true")
- (const_string "false")))
+ ] (const_string "false")))
(define_delay (eq_attr "type" "call")
[(eq_attr "in_call_delay" "true") (nil) (nil)])
(define_delay (eq_attr "type" "sibcall")
- [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
+ [(eq_attr "in_sibcall_delay" "true") (nil) (nil)])
+
+(define_delay (eq_attr "type" "return")
+ [(eq_attr "in_return_delay" "true") (nil) (nil)])
(define_delay (eq_attr "type" "branch")
- [(eq_attr "in_branch_delay" "true")
- (nil) (eq_attr "in_annul_branch_delay" "true")])
+ [(eq_attr "in_branch_delay" "true") (nil) (eq_attr "in_branch_delay" "true")])
(define_delay (eq_attr "type" "uncond_branch")
- [(eq_attr "in_uncond_branch_delay" "true")
- (nil) (nil)])
-
-(define_delay (eq_attr "type" "return")
- [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
+ [(eq_attr "in_branch_delay" "true") (nil) (nil)])
;; Include SPARC DFA schedulers
@@ -3513,7 +3503,8 @@
"TARGET_FPU"
"fdtos\t%1, %0"
[(set_attr "type" "fp")
- (set_attr "fptype" "double")])
+ (set_attr "fptype" "double")
+ (set_attr "fptype_ut699" "single")])
(define_expand "trunctfsf2"
[(set (match_operand:SF 0 "register_operand" "")
@@ -3554,7 +3545,7 @@
"TARGET_FPU"
"fitos\t%1, %0"
[(set_attr "type" "fp")
- (set_attr "fptype" "double")])
+ (set_attr "fptype" "single")])
(define_insn "floatsidf2"
[(set (match_operand:DF 0 "register_operand" "=e")
@@ -3641,7 +3632,7 @@
"TARGET_FPU"
"fstoi\t%1, %0"
[(set_attr "type" "fp")
- (set_attr "fptype" "double")])
+ (set_attr "fptype" "single")])
(define_insn "fix_truncdfsi2"
[(set (match_operand:SI 0 "register_operand" "=f")
@@ -3649,7 +3640,8 @@
"TARGET_FPU"
"fdtoi\t%1, %0"
[(set_attr "type" "fp")
- (set_attr "fptype" "double")])
+ (set_attr "fptype" "double")
+ (set_attr "fptype_ut699" "single")])
(define_expand "fix_trunctfsi2"
[(set (match_operand:SI 0 "register_operand" "")
@@ -5548,7 +5540,7 @@
[(set (match_operand:DF 0 "register_operand" "=e")
(mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
(float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
- "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
+ "(TARGET_V8 || TARGET_V9) && TARGET_FPU && !sparc_fix_ut699"
"fsmuld\t%1, %2, %0"
[(set_attr "type" "fpmul")
(set_attr "fptype" "double")])
@@ -5575,73 +5567,89 @@
(match_operand:TF 2 "register_operand" "e")))]
"TARGET_FPU && TARGET_HARD_QUAD"
"fdivq\t%1, %2, %0"
- [(set_attr "type" "fpdivd")])
+ [(set_attr "type" "fpdivs")])
-(define_insn "divdf3"
+(define_expand "divdf3"
[(set (match_operand:DF 0 "register_operand" "=e")
(div:DF (match_operand:DF 1 "register_operand" "e")
(match_operand:DF 2 "register_operand" "e")))]
"TARGET_FPU"
+ "")
+
+(define_insn "*divdf3_nofix"
+ [(set (match_operand:DF 0 "register_operand" "=e")
+ (div:DF (match_operand:DF 1 "register_operand" "e")
+ (match_operand:DF 2 "register_operand" "e")))]
+ "TARGET_FPU && !sparc_fix_ut699"
"fdivd\t%1, %2, %0"
[(set_attr "type" "fpdivd")
(set_attr "fptype" "double")])
+(define_insn "*divdf3_fix"
+ [(set (match_operand:DF 0 "register_operand" "=e")
+ (div:DF (match_operand:DF 1 "register_operand" "e")
+ (match_operand:DF 2 "register_operand" "e")))]
+ "TARGET_FPU && sparc_fix_ut699"
+ "fdivd\t%1, %2, %0\n\tstd\t%0, [%%sp-8]"
+ [(set_attr "type" "fpdivd")
+ (set_attr "fptype" "double")
+ (set_attr "length" "2")])
+
(define_insn "divsf3"
[(set (match_operand:SF 0 "register_operand" "=f")
(div:SF (match_operand:SF 1 "register_operand" "f")
(match_operand:SF 2 "register_operand" "f")))]
- "TARGET_FPU"
+ "TARGET_FPU && !sparc_fix_ut699"
"fdivs\t%1, %2, %0"
[(set_attr "type" "fpdivs")])
(define_expand "negtf2"
- [(set (match_operand:TF 0 "register_operand" "=e,e")
- (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
+ [(set (match_operand:TF 0 "register_operand" "")
+ (neg:TF (match_operand:TF 1 "register_operand" "")))]
"TARGET_FPU"
"")
-(define_insn_and_split "*negtf2_notv9"
- [(set (match_operand:TF 0 "register_operand" "=e,e")
- (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
- ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
- "TARGET_FPU
- && ! TARGET_V9"
- "@
- fnegs\t%0, %0
- #"
- "&& reload_completed
- && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
- [(set (match_dup 2) (neg:SF (match_dup 3)))
- (set (match_dup 4) (match_dup 5))
- (set (match_dup 6) (match_dup 7))]
- "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
- operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
- operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
- operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
- operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
- operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
- [(set_attr "type" "fpmove,*")
- (set_attr "length" "*,2")])
-
-(define_insn_and_split "*negtf2_v9"
- [(set (match_operand:TF 0 "register_operand" "=e,e")
- (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
- ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
- "TARGET_FPU && TARGET_V9"
- "@
- fnegd\t%0, %0
- #"
- "&& reload_completed
- && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
- [(set (match_dup 2) (neg:DF (match_dup 3)))
- (set (match_dup 4) (match_dup 5))]
- "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
- operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
- operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
- operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
- [(set_attr "type" "fpmove,*")
- (set_attr "length" "*,2")
- (set_attr "fptype" "double")])
+(define_insn "*negtf2_hq"
+ [(set (match_operand:TF 0 "register_operand" "=e")
+ (neg:TF (match_operand:TF 1 "register_operand" "e")))]
+ "TARGET_FPU && TARGET_HARD_QUAD"
+ "fnegq\t%1, %0"
+ [(set_attr "type" "fpmove")])
+
+(define_insn_and_split "*negtf2"
+ [(set (match_operand:TF 0 "register_operand" "=e")
+ (neg:TF (match_operand:TF 1 "register_operand" "e")))]
+ "TARGET_FPU && !TARGET_HARD_QUAD"
+ "#"
+ "&& reload_completed"
+ [(clobber (const_int 0))]
+{
+ rtx set_dest = operands[0];
+ rtx set_src = operands[1];
+ rtx dest1, dest2;
+ rtx src1, src2;
+
+ dest1 = gen_df_reg (set_dest, 0);
+ dest2 = gen_df_reg (set_dest, 1);
+ src1 = gen_df_reg (set_src, 0);
+ src2 = gen_df_reg (set_src, 1);
+
+ /* Now emit using the real source and destination we found, swapping
+ the order if we detect overlap. */
+ if (reg_overlap_mentioned_p (dest1, src2))
+ {
+ emit_insn (gen_movdf (dest2, src2));
+ emit_insn (gen_negdf2 (dest1, src1));
+ }
+ else
+ {
+ emit_insn (gen_negdf2 (dest1, src1));
+ if (REGNO (dest2) != REGNO (src2))
+ emit_insn (gen_movdf (dest2, src2));
+ }
+ DONE;
+}
+ [(set_attr "length" "2")])
(define_expand "negdf2"
[(set (match_operand:DF 0 "register_operand" "")
@@ -5650,22 +5658,39 @@
"")
(define_insn_and_split "*negdf2_notv9"
- [(set (match_operand:DF 0 "register_operand" "=e,e")
- (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
- "TARGET_FPU && ! TARGET_V9"
- "@
- fnegs\t%0, %0
- #"
- "&& reload_completed
- && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
- [(set (match_dup 2) (neg:SF (match_dup 3)))
- (set (match_dup 4) (match_dup 5))]
- "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
- operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
- operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
- operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
- [(set_attr "type" "fpmove,*")
- (set_attr "length" "*,2")])
+ [(set (match_operand:DF 0 "register_operand" "=e")
+ (neg:DF (match_operand:DF 1 "register_operand" "e")))]
+ "TARGET_FPU && !TARGET_V9"
+ "#"
+ "&& reload_completed"
+ [(clobber (const_int 0))]
+{
+ rtx set_dest = operands[0];
+ rtx set_src = operands[1];
+ rtx dest1, dest2;
+ rtx src1, src2;
+
+ dest1 = gen_highpart (SFmode, set_dest);
+ dest2 = gen_lowpart (SFmode, set_dest);
+ src1 = gen_highpart (SFmode, set_src);
+ src2 = gen_lowpart (SFmode, set_src);
+
+ /* Now emit using the real source and destination we found, swapping
+ the order if we detect overlap. */
+ if (reg_overlap_mentioned_p (dest1, src2))
+ {
+ emit_insn (gen_movsf (dest2, src2));
+ emit_insn (gen_negsf2 (dest1, src1));
+ }
+ else
+ {
+ emit_insn (gen_negsf2 (dest1, src1));
+ if (REGNO (dest2) != REGNO (src2))
+ emit_insn (gen_movsf (dest2, src2));
+ }
+ DONE;
+}
+ [(set_attr "length" "2")])
(define_insn "*negdf2_v9"
[(set (match_operand:DF 0 "register_operand" "=e")
@@ -5688,56 +5713,47 @@
"TARGET_FPU"
"")
-(define_insn_and_split "*abstf2_notv9"
- [(set (match_operand:TF 0 "register_operand" "=e,e")
- (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
- ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
- "TARGET_FPU && ! TARGET_V9"
- "@
- fabss\t%0, %0
- #"
- "&& reload_completed
- && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
- [(set (match_dup 2) (abs:SF (match_dup 3)))
- (set (match_dup 4) (match_dup 5))
- (set (match_dup 6) (match_dup 7))]
- "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
- operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
- operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
- operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
- operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
- operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
- [(set_attr "type" "fpmove,*")
- (set_attr "length" "*,2")])
-
-(define_insn "*abstf2_hq_v9"
- [(set (match_operand:TF 0 "register_operand" "=e,e")
- (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
- "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
- "@
- fabsd\t%0, %0
- fabsq\t%1, %0"
- [(set_attr "type" "fpmove")
- (set_attr "fptype" "double,*")])
+(define_insn "*abstf2_hq"
+ [(set (match_operand:TF 0 "register_operand" "=e")
+ (abs:TF (match_operand:TF 1 "register_operand" "e")))]
+ "TARGET_FPU && TARGET_HARD_QUAD"
+ "fabsq\t%1, %0"
+ [(set_attr "type" "fpmove")])
-(define_insn_and_split "*abstf2_v9"
- [(set (match_operand:TF 0 "register_operand" "=e,e")
- (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
- "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
- "@
- fabsd\t%0, %0
- #"
- "&& reload_completed
- && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
- [(set (match_dup 2) (abs:DF (match_dup 3)))
- (set (match_dup 4) (match_dup 5))]
- "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
- operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
- operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
- operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
- [(set_attr "type" "fpmove,*")
- (set_attr "length" "*,2")
- (set_attr "fptype" "double,*")])
+(define_insn_and_split "*abstf2"
+ [(set (match_operand:TF 0 "register_operand" "=e")
+ (abs:TF (match_operand:TF 1 "register_operand" "e")))]
+ "TARGET_FPU && !TARGET_HARD_QUAD"
+ "#"
+ "&& reload_completed"
+ [(clobber (const_int 0))]
+{
+ rtx set_dest = operands[0];
+ rtx set_src = operands[1];
+ rtx dest1, dest2;
+ rtx src1, src2;
+
+ dest1 = gen_df_reg (set_dest, 0);
+ dest2 = gen_df_reg (set_dest, 1);
+ src1 = gen_df_reg (set_src, 0);
+ src2 = gen_df_reg (set_src, 1);
+
+ /* Now emit using the real source and destination we found, swapping
+ the order if we detect overlap. */
+ if (reg_overlap_mentioned_p (dest1, src2))
+ {
+ emit_insn (gen_movdf (dest2, src2));
+ emit_insn (gen_absdf2 (dest1, src1));
+ }
+ else
+ {
+ emit_insn (gen_absdf2 (dest1, src1));
+ if (REGNO (dest2) != REGNO (src2))
+ emit_insn (gen_movdf (dest2, src2));
+ }
+ DONE;
+}
+ [(set_attr "length" "2")])
(define_expand "absdf2"
[(set (match_operand:DF 0 "register_operand" "")
@@ -5746,22 +5762,39 @@
"")
(define_insn_and_split "*absdf2_notv9"
- [(set (match_operand:DF 0 "register_operand" "=e,e")
- (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
- "TARGET_FPU && ! TARGET_V9"
- "@
- fabss\t%0, %0
- #"
- "&& reload_completed
- && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
- [(set (match_dup 2) (abs:SF (match_dup 3)))
- (set (match_dup 4) (match_dup 5))]
- "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
- operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
- operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
- operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
- [(set_attr "type" "fpmove,*")
- (set_attr "length" "*,2")])
+ [(set (match_operand:DF 0 "register_operand" "=e")
+ (abs:DF (match_operand:DF 1 "register_operand" "e")))]
+ "TARGET_FPU && !TARGET_V9"
+ "#"
+ "&& reload_completed"
+ [(clobber (const_int 0))]
+{
+ rtx set_dest = operands[0];
+ rtx set_src = operands[1];
+ rtx dest1, dest2;
+ rtx src1, src2;
+
+ dest1 = gen_highpart (SFmode, set_dest);
+ dest2 = gen_lowpart (SFmode, set_dest);
+ src1 = gen_highpart (SFmode, set_src);
+ src2 = gen_lowpart (SFmode, set_src);
+
+ /* Now emit using the real source and destination we found, swapping
+ the order if we detect overlap. */
+ if (reg_overlap_mentioned_p (dest1, src2))
+ {
+ emit_insn (gen_movsf (dest2, src2));
+ emit_insn (gen_abssf2 (dest1, src1));
+ }
+ else
+ {
+ emit_insn (gen_abssf2 (dest1, src1));
+ if (REGNO (dest2) != REGNO (src2))
+ emit_insn (gen_movsf (dest2, src2));
+ }
+ DONE;
+}
+ [(set_attr "length" "2")])
(define_insn "*absdf2_v9"
[(set (match_operand:DF 0 "register_operand" "=e")
@@ -5789,20 +5822,35 @@
(sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
"TARGET_FPU && TARGET_HARD_QUAD"
"fsqrtq\t%1, %0"
- [(set_attr "type" "fpsqrtd")])
+ [(set_attr "type" "fpsqrts")])
-(define_insn "sqrtdf2"
+(define_expand "sqrtdf2"
[(set (match_operand:DF 0 "register_operand" "=e")
(sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
"TARGET_FPU"
+ "")
+
+(define_insn "*sqrtdf2_nofix"
+ [(set (match_operand:DF 0 "register_operand" "=e")
+ (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
+ "TARGET_FPU && !sparc_fix_ut699"
"fsqrtd\t%1, %0"
[(set_attr "type" "fpsqrtd")
(set_attr "fptype" "double")])
+(define_insn "*sqrtdf2_fix"
+ [(set (match_operand:DF 0 "register_operand" "=e")
+ (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
+ "TARGET_FPU && sparc_fix_ut699"
+ "fsqrtd\t%1, %0\n\tstd\t%0, [%%sp-8]"
+ [(set_attr "type" "fpsqrtd")
+ (set_attr "fptype" "double")
+ (set_attr "length" "2")])
+
(define_insn "sqrtsf2"
[(set (match_operand:SF 0 "register_operand" "=f")
(sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
- "TARGET_FPU"
+ "TARGET_FPU && !sparc_fix_ut699"
"fsqrts\t%1, %0"
[(set_attr "type" "fpsqrts")])
@@ -5821,19 +5869,6 @@
}
[(set_attr "type" "shift")])
-(define_insn "*ashlsi3_extend"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI
- (ashift:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "arith_operand" "rI"))))]
- "TARGET_ARCH64"
-{
- if (GET_CODE (operands[2]) == CONST_INT)
- operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
- return "sll\t%1, %2, %0";
-}
- [(set_attr "type" "shift")])
-
(define_expand "ashldi3"
[(set (match_operand:DI 0 "register_operand" "=r")
(ashift:DI (match_operand:DI 1 "register_operand" "r")