diff options
Diffstat (limited to 'gcc-4.9/gcc/config/sparc/sparc.md')
-rw-r--r-- | gcc-4.9/gcc/config/sparc/sparc.md | 304 |
1 files changed, 161 insertions, 143 deletions
diff --git a/gcc-4.9/gcc/config/sparc/sparc.md b/gcc-4.9/gcc/config/sparc/sparc.md index 8b6c647fc..76c331597 100644 --- a/gcc-4.9/gcc/config/sparc/sparc.md +++ b/gcc-4.9/gcc/config/sparc/sparc.md @@ -424,6 +424,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")) @@ -464,7 +468,8 @@ (const_string "false") (and (eq_attr "fix_ut699" "true") (and (eq_attr "type" "fpload,fp,fpmove,fpmul,fpdivs,fpsqrts") - (eq_attr "fptype" "single"))) + (ior (eq_attr "fptype" "single") + (eq_attr "fptype_ut699" "single")))) (const_string "false") (eq_attr "length" "1") (const_string "true") @@ -3455,7 +3460,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" "") @@ -3496,7 +3502,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") @@ -3583,7 +3589,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") @@ -3591,7 +3597,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" "") @@ -5554,53 +5561,52 @@ [(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" "") @@ -5609,22 +5615,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") @@ -5647,56 +5670,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" "") @@ -5705,22 +5719,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") @@ -5795,19 +5826,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") |