diff options
Diffstat (limited to 'gcc/config/rs6000/rs6000.md')
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 101 |
1 files changed, 87 insertions, 14 deletions
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 14b73c213a8..ce774b187b2 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -176,7 +176,9 @@ (define_mode_macro FP [(SF "TARGET_HARD_FLOAT") (DF "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)") (TF "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128")]) + && TARGET_HARD_FLOAT + && (TARGET_FPRS || TARGET_E500_DOUBLE) + && TARGET_LONG_DOUBLE_128")]) ; Various instructions that come in SI and DI forms. ; A generic w/d attribute, for things like cmpw/cmpd. @@ -5730,7 +5732,7 @@ (clobber (match_dup 4)) (clobber (match_dup 5)) (clobber (match_dup 6))])] - "TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)" " { if (TARGET_E500_DOUBLE) @@ -8538,7 +8540,7 @@ [(set_attr "length" "8,8,8,20,20,16")]) (define_insn_and_split "*movtf_softfloat" - [(set (match_operand:TF 0 "nonimmediate_operand" "=r,Y,r") + [(set (match_operand:TF 0 "rs6000_nonimmediate_operand" "=r,Y,r") (match_operand:TF 1 "input_operand" "YGHF,r,r"))] "!TARGET_IEEEQUAD && (TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_LONG_DOUBLE_128 @@ -8551,6 +8553,21 @@ [(set_attr "length" "20,20,16")]) (define_expand "extenddftf2" + [(set (match_operand:TF 0 "nonimmediate_operand" "") + (float_extend:TF (match_operand:DF 1 "input_operand" "")))] + "!TARGET_IEEEQUAD + && TARGET_HARD_FLOAT + && (TARGET_FPRS || TARGET_E500_DOUBLE) + && TARGET_LONG_DOUBLE_128" +{ + if (TARGET_E500_DOUBLE) + emit_insn (gen_spe_extenddftf2 (operands[0], operands[1])); + else + emit_insn (gen_extenddftf2_fprs (operands[0], operands[1])); + DONE; +}) + +(define_expand "extenddftf2_fprs" [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "") (float_extend:TF (match_operand:DF 1 "input_operand" ""))) (use (match_dup 2))])] @@ -8586,7 +8603,9 @@ [(set (match_operand:TF 0 "nonimmediate_operand" "") (float_extend:TF (match_operand:SF 1 "gpc_reg_operand" "")))] "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" + && TARGET_HARD_FLOAT + && (TARGET_FPRS || TARGET_E500_DOUBLE) + && TARGET_LONG_DOUBLE_128" { rtx tmp = gen_reg_rtx (DFmode); emit_insn (gen_extendsfdf2 (tmp, operands[1])); @@ -8598,7 +8617,9 @@ [(set (match_operand:DF 0 "gpc_reg_operand" "") (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "")))] "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" + && TARGET_HARD_FLOAT + && (TARGET_FPRS || TARGET_E500_DOUBLE) + && TARGET_LONG_DOUBLE_128" "") (define_insn_and_split "trunctfdf2_internal1" @@ -8625,7 +8646,22 @@ "fadd %0,%1,%L1" [(set_attr "type" "fp")]) -(define_insn_and_split "trunctfsf2" +(define_expand "trunctfsf2" + [(set (match_operand:SF 0 "gpc_reg_operand" "") + (float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "")))] + "!TARGET_IEEEQUAD + && TARGET_HARD_FLOAT + && (TARGET_FPRS || TARGET_E500_DOUBLE) + && TARGET_LONG_DOUBLE_128" +{ + if (TARGET_E500_DOUBLE) + emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1])); + else + emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1])); + DONE; +}) + +(define_insn_and_split "trunctfsf2_fprs" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "f"))) (clobber (match_scratch:DF 2 "=f"))] @@ -8643,7 +8679,9 @@ [(set (match_operand:TF 0 "gpc_reg_operand" "") (float:TF (match_operand:SI 1 "gpc_reg_operand" "")))] "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" + && TARGET_HARD_FLOAT + && (TARGET_FPRS || TARGET_E500_DOUBLE) + && TARGET_LONG_DOUBLE_128" { rtx tmp = gen_reg_rtx (DFmode); expand_float (tmp, operands[1], false); @@ -8664,6 +8702,22 @@ (set_attr "length" "20")]) (define_expand "fix_trunctfsi2" + [(set (match_operand:SI 0 "gpc_reg_operand" "") + (fix:SI (match_operand:TF 1 "gpc_reg_operand" "")))] + "!TARGET_IEEEQUAD + && (TARGET_POWER2 || TARGET_POWERPC) + && TARGET_HARD_FLOAT + && (TARGET_FPRS || TARGET_E500_DOUBLE) + && TARGET_LONG_DOUBLE_128" +{ + if (TARGET_E500_DOUBLE) + emit_insn (gen_spe_fix_trunctfsi2 (operands[0], operands[1])); + else + emit_insn (gen_fix_trunctfsi2_fprs (operands[0], operands[1])); + DONE; +}) + +(define_expand "fix_trunctfsi2_fprs" [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "") (fix:SI (match_operand:TF 1 "gpc_reg_operand" ""))) (clobber (match_dup 2)) @@ -8705,7 +8759,16 @@ DONE; }) -(define_insn "negtf2" +(define_expand "negtf2" + [(set (match_operand:TF 0 "gpc_reg_operand" "") + (neg:TF (match_operand:TF 1 "gpc_reg_operand" "")))] + "!TARGET_IEEEQUAD + && TARGET_HARD_FLOAT + && (TARGET_FPRS || TARGET_E500_DOUBLE) + && TARGET_LONG_DOUBLE_128" + "") + +(define_insn "negtf2_internal" [(set (match_operand:TF 0 "gpc_reg_operand" "=f") (neg:TF (match_operand:TF 1 "gpc_reg_operand" "f")))] "!TARGET_IEEEQUAD @@ -8721,14 +8784,24 @@ (set_attr "length" "8")]) (define_expand "abstf2" - [(set (match_operand:TF 0 "gpc_reg_operand" "=f") - (abs:TF (match_operand:TF 1 "gpc_reg_operand" "f")))] + [(set (match_operand:TF 0 "gpc_reg_operand" "") + (abs:TF (match_operand:TF 1 "gpc_reg_operand" "")))] "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" + && TARGET_HARD_FLOAT + && (TARGET_FPRS || TARGET_E500_DOUBLE) + && TARGET_LONG_DOUBLE_128" " { rtx label = gen_label_rtx (); - emit_insn (gen_abstf2_internal (operands[0], operands[1], label)); + if (TARGET_E500_DOUBLE) + { + if (flag_unsafe_math_optimizations) + emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label)); + else + emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label)); + } + else + emit_insn (gen_abstf2_internal (operands[0], operands[1], label)); emit_label (label); DONE; }") @@ -8761,7 +8834,7 @@ ; List r->r after r->"o<>", otherwise reload will try to reload a ; non-offsettable address by using r->r which won't make progress. (define_insn "*movdi_internal32" - [(set (match_operand:DI 0 "nonimmediate_operand" "=o<>,r,r,*f,*f,m,r") + [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "=o<>,r,r,*f,*f,m,r") (match_operand:DI 1 "input_operand" "r,r,m,f,m,f,IJKnGHF"))] "! TARGET_POWERPC64 && (gpc_reg_operand (operands[0], DImode) @@ -8798,7 +8871,7 @@ }") (define_split - [(set (match_operand:DI 0 "nonimmediate_operand" "") + [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "") (match_operand:DI 1 "input_operand" ""))] "reload_completed && !TARGET_POWERPC64 && gpr_or_gpr_p (operands[0], operands[1])" |