summaryrefslogtreecommitdiff
path: root/gcc/config/rs6000/rs6000.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/rs6000/rs6000.md')
-rw-r--r--gcc/config/rs6000/rs6000.md101
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])"