+2004-10-22 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/spe.md (spe_extendsfdf2): New.
+ (movdf_e500_double): New.
+ (spe_truncdfsf2): New.
+ (spe_absdf2): New.
+ (spe_nabsdf2): New.
+ (spe_negdf2): New.
+ (sub_adddf3): New.
+ (spe_subdf3): New.
+ (spe_muldf3): New.
+ (spe_floatsidf2): New.
+ (spe_floatunssidf2): New.
+ (fix_truncdfsi2): New.
+ (spe_fixuns_truncdfsi2): New.
+
+ * config/rs6000/rs6000.md (truncdfsf2): Change to expander.
+ (fpr_truncdfsf2): New.
+ (negdf2): Change to expander.
+ (fpr_negdf2): New.
+ (fpr_nabsdf2): Name pattern.
+ (adddf3): Change to expander.
+ (fpr_adddf3): Nem.
+ (subdf3): Change to expander.
+ (fpr_subdf3): New.
+ (muldf3): Change to expander.
+ (fpr_muldf3): New.
+ (divdf3): Change to expander.
+ (fpr_divdf3): New.
+ (movdf_softfloat32): Change !TARGET_FPRS to TARGET_E500_SINGLE.
+ (cmpdf): Allow for TARGET_E500_DOUBLE.
+
2004-10-22 Kazu Hirata <kazu@cs.umass.edu>
* c-semantics.c (re_push_stmt_list): Remove.
}
[(set_attr "type" "fp")])
-(define_insn "truncdfsf2"
+(define_expand "truncdfsf2"
+ [(set (match_operand:SF 0 "gpc_reg_operand" "")
+ (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
+ "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+ "")
+
+(define_insn "fpr_truncdfsf2"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "f")))]
"TARGET_HARD_FLOAT && TARGET_FPRS"
"fsel %0,%1,%2,%3"
[(set_attr "type" "fp")])
-(define_insn "negdf2"
+(define_expand "negdf2"
+ [(set (match_operand:DF 0 "gpc_reg_operand" "")
+ (neg:DF (match_operand:DF 1 "gpc_reg_operand" "")))]
+ "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+ "")
+
+(define_insn "fpr_negdf2"
[(set (match_operand:DF 0 "gpc_reg_operand" "=f")
(neg:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
"TARGET_HARD_FLOAT && TARGET_FPRS"
"fneg %0,%1"
[(set_attr "type" "fp")])
-(define_insn "absdf2"
+(define_expand "absdf2"
+ [(set (match_operand:DF 0 "gpc_reg_operand" "")
+ (abs:DF (match_operand:DF 1 "gpc_reg_operand" "")))]
+ "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+ "")
+
+(define_insn "fpr_absdf2"
[(set (match_operand:DF 0 "gpc_reg_operand" "=f")
(abs:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
"TARGET_HARD_FLOAT && TARGET_FPRS"
"fabs %0,%1"
[(set_attr "type" "fp")])
-(define_insn ""
+(define_insn "fpr_nabsdf2"
[(set (match_operand:DF 0 "gpc_reg_operand" "=f")
(neg:DF (abs:DF (match_operand:DF 1 "gpc_reg_operand" "f"))))]
"TARGET_HARD_FLOAT && TARGET_FPRS"
"fnabs %0,%1"
[(set_attr "type" "fp")])
-(define_insn "adddf3"
+(define_expand "adddf3"
+ [(set (match_operand:DF 0 "gpc_reg_operand" "")
+ (plus:DF (match_operand:DF 1 "gpc_reg_operand" "")
+ (match_operand:DF 2 "gpc_reg_operand" "")))]
+ "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+ "")
+
+(define_insn "fpr_adddf3"
[(set (match_operand:DF 0 "gpc_reg_operand" "=f")
(plus:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
(match_operand:DF 2 "gpc_reg_operand" "f")))]
"{fa|fadd} %0,%1,%2"
[(set_attr "type" "fp")])
-(define_insn "subdf3"
+(define_expand "subdf3"
+ [(set (match_operand:DF 0 "gpc_reg_operand" "")
+ (minus:DF (match_operand:DF 1 "gpc_reg_operand" "")
+ (match_operand:DF 2 "gpc_reg_operand" "")))]
+ "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+ "")
+
+(define_insn "fpr_subdf3"
[(set (match_operand:DF 0 "gpc_reg_operand" "=f")
(minus:DF (match_operand:DF 1 "gpc_reg_operand" "f")
(match_operand:DF 2 "gpc_reg_operand" "f")))]
"{fs|fsub} %0,%1,%2"
[(set_attr "type" "fp")])
-(define_insn "muldf3"
+(define_expand "muldf3"
+ [(set (match_operand:DF 0 "gpc_reg_operand" "")
+ (mult:DF (match_operand:DF 1 "gpc_reg_operand" "")
+ (match_operand:DF 2 "gpc_reg_operand" "")))]
+ "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+ "")
+
+(define_insn "fpr_muldf3"
[(set (match_operand:DF 0 "gpc_reg_operand" "=f")
(mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
(match_operand:DF 2 "gpc_reg_operand" "f")))]
"{fm|fmul} %0,%1,%2"
[(set_attr "type" "dmul")])
-(define_insn "divdf3"
+(define_expand "divdf3"
+ [(set (match_operand:DF 0 "gpc_reg_operand" "")
+ (div:DF (match_operand:DF 1 "gpc_reg_operand" "")
+ (match_operand:DF 2 "gpc_reg_operand" "")))]
+ "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+ "")
+
+(define_insn "fpr_divdf3"
[(set (match_operand:DF 0 "gpc_reg_operand" "=f")
(div:DF (match_operand:DF 1 "gpc_reg_operand" "f")
(match_operand:DF 2 "gpc_reg_operand" "f")))]
(define_insn "*movdf_softfloat32"
[(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,r,r,r")
(match_operand:DF 1 "input_operand" "r,m,r,G,H,F"))]
- "! TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
+ "! TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || TARGET_E500_SINGLE)
&& (gpc_reg_operand (operands[0], DFmode)
|| gpc_reg_operand (operands[1], DFmode))"
"*
(define_expand "cmpdf"
[(set (cc0) (compare (match_operand:DF 0 "gpc_reg_operand" "")
(match_operand:DF 1 "gpc_reg_operand" "")))]
- "TARGET_HARD_FLOAT && TARGET_FPRS"
+ "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
"
{
rs6000_compare_op0 = operands[0];
"efsdiv %0,%1,%2"
[(set_attr "type" "vecfdiv")])
+;; Floating point conversion instructions.
+
+(define_insn "fixuns_truncdfsi2"
+ [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
+ (unsigned_fix:SI (match_operand:DF 1 "gpc_reg_operand" "r")))]
+ "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE"
+ "efdctuiz %0,%1"
+ [(set_attr "type" "fp")])
+
+;; FIXME: fix expander.
+(define_insn "spe_extendsfdf2"
+ [(set (match_operand:DF 0 "gpc_reg_operand" "=r")
+ (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "r")))]
+ "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE"
+ "efdcfs %0,%1"
+ [(set_attr "type" "fp")])
+
(define_insn "spe_fixuns_truncsfsi2"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(unsigned_fix:SI (match_operand:SF 1 "gpc_reg_operand" "r")))]
"efsctsiz %0,%1"
[(set_attr "type" "fp")])
+;; FIXME: fix expander.
+(define_insn "spe_fix_truncdfsi2"
+ [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
+ (fix:SI (match_operand:DF 1 "gpc_reg_operand" "r")))]
+ "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE"
+ "efdctsiz %0,%1"
+ [(set_attr "type" "fp")])
+
(define_insn "spe_floatunssisf2"
[(set (match_operand:SF 0 "gpc_reg_operand" "=r")
(unsigned_float:SF (match_operand:SI 1 "gpc_reg_operand" "r")))]
"efscfui %0,%1"
[(set_attr "type" "fp")])
+;; FIXME: fix expander.
+(define_insn "spe_floatunssidf2"
+ [(set (match_operand:DF 0 "gpc_reg_operand" "=r")
+ (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))]
+ "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE"
+ "efdcfui %0,%1"
+ [(set_attr "type" "fp")])
+
(define_insn "spe_floatsisf2"
[(set (match_operand:SF 0 "gpc_reg_operand" "=r")
(float:SF (match_operand:SI 1 "gpc_reg_operand" "r")))]
"efscfsi %0,%1"
[(set_attr "type" "fp")])
+;; FIXME: fix expander.
+(define_insn "spe_floatsidf2"
+ [(set (match_operand:DF 0 "gpc_reg_operand" "=r")
+ (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))]
+ "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE"
+ "efdcfsi %0,%1"
+ [(set_attr "type" "fp")])
;; SPE SIMD instructions
[(set_attr "type" "vecstore")
(set_attr "length" "4")])
+;; Double-precision floating point instructions.
+(define_insn "*movdf_e500_double"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
+ (match_operand:DF 1 "input_operand" "r,m,r"))]
+ "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE
+ && (gpc_reg_operand (operands[0], DFmode)
+ || gpc_reg_operand (operands[1], DFmode))"
+ "*
+ {
+ switch (which_alternative)
+ {
+ case 0:
+ return \"evor %0,%1,%1\";
+ case 1:
+ return \"evldd%X1 %0,%y1\";
+ case 2:
+ return \"evstdd%X0 %1,%y0\";
+ default:
+ abort ();
+ }
+ }"
+ [(set_attr "type" "*,vecload,vecstore")
+ (set_attr "length" "*,*,*")])
+
+(define_insn "spe_truncdfsf2"
+ [(set (match_operand:SF 0 "gpc_reg_operand" "=r")
+ (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "r")))]
+ "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE"
+ "efscfd %0,%1")
+
+(define_insn "spe_absdf2"
+ [(set (match_operand:DF 0 "gpc_reg_operand" "=r")
+ (abs:DF (match_operand:DF 1 "gpc_reg_operand" "r")))]
+ "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE"
+ "efdabs %0,%1")
+
+(define_insn "spe_nabsdf2"
+ [(set (match_operand:DF 0 "gpc_reg_operand" "=r")
+ (neg:DF (abs:DF (match_operand:DF 1 "gpc_reg_operand" "r"))))]
+ "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE"
+ "efdnabs %0,%1")
+
+(define_insn "spe_negdf2"
+ [(set (match_operand:DF 0 "gpc_reg_operand" "=r")
+ (neg:DF (match_operand:DF 1 "gpc_reg_operand" "r")))]
+ "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE"
+ "efdneg %0,%1")
+
+(define_insn "spe_adddf3"
+ [(set (match_operand:DF 0 "gpc_reg_operand" "=r")
+ (plus:DF (match_operand:DF 1 "gpc_reg_operand" "r")
+ (match_operand:DF 2 "gpc_reg_operand" "r")))]
+ "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE"
+ "efdadd %0,%1,%2")
+
+(define_insn "spe_subdf3"
+ [(set (match_operand:DF 0 "gpc_reg_operand" "=r")
+ (minus:DF (match_operand:DF 1 "gpc_reg_operand" "r")
+ (match_operand:DF 2 "gpc_reg_operand" "r")))]
+ "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE"
+ "efdsub %0,%1,%2")
+
+(define_insn "spe_muldf3"
+ [(set (match_operand:DF 0 "gpc_reg_operand" "=r")
+ (mult:DF (match_operand:DF 1 "gpc_reg_operand" "r")
+ (match_operand:DF 2 "gpc_reg_operand" "r")))]
+ "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE"
+ "efdmul %0,%1,%2")
+
+(define_insn "spe_divdf3"
+ [(set (match_operand:DF 0 "gpc_reg_operand" "=r")
+ (div:DF (match_operand:DF 1 "gpc_reg_operand" "r")
+ (match_operand:DF 2 "gpc_reg_operand" "r")))]
+ "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE"
+ "efddiv %0,%1,%2")
+
;; Vector move instructions.
(define_expand "movv2si"