Commit 94d7001a by Richard Kenner

(movsfcc, movdfcc): New standard patterns.

(fselsfsf4, fseldfsf4, fseldfdf4, fselsfdf4): Name and create variants of
existing anonymous patterns for movsfcc and movdfcc.

From-SVN: r9031
parent cb649530
...@@ -2732,9 +2732,9 @@ ...@@ -2732,9 +2732,9 @@
"fsqrt %0,%1" "fsqrt %0,%1"
[(set_attr "type" "dsqrt")]) [(set_attr "type" "dsqrt")])
;; For SMIN, SMAX, UMIN, and UMAX, we use DEFINE_EXPAND's that involve a fsel ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
;; instruction and some auxiliary computations. Then we just have a single ;; fsel instruction and some auxiliary computations. Then we just have a
;; DEFINE_INSN for fsel and the define_splits to make them if made by ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
;; combine. ;; combine.
(define_expand "maxsf3" (define_expand "maxsf3"
[(set (match_dup 3) [(set (match_dup 3)
...@@ -2792,7 +2792,76 @@ ...@@ -2792,7 +2792,76 @@
(match_dup 2)))] (match_dup 2)))]
"") "")
(define_insn "" (define_expand "movsfcc"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(if_then_else:SF (match_operand 1 "comparison_operator" "")
(match_operand:SF 2 "gpc_reg_operand" "f")
(match_operand:SF 3 "gpc_reg_operand" "f")))]
"TARGET_PPC_GFXOPT"
"
{
rtx temp, op0, op1;
enum rtx_code code = GET_CODE (operands[1]);
if (! rs6000_compare_fp_p)
FAIL;
switch (code)
{
case GE: case EQ: case NE:
op0 = rs6000_compare_op0;
op1 = rs6000_compare_op1;
break;
case GT:
op0 = rs6000_compare_op1;
op1 = rs6000_compare_op0;
temp = operands[2]; operands[2] = operands[3]; operands[3] = temp;
break;
case LE:
op0 = rs6000_compare_op1;
op1 = rs6000_compare_op0;
break;
case LT:
op0 = rs6000_compare_op0;
op1 = rs6000_compare_op1;
temp = operands[2]; operands[2] = operands[3]; operands[3] = temp;
break;
default:
FAIL;
}
if (GET_MODE (rs6000_compare_op0) == DFmode)
{
temp = gen_reg_rtx (DFmode);
emit_insn (gen_subdf3 (temp, op0, op1));
emit_insn (gen_fseldfsf4 (operands[0], temp, operands[2], operands[3]));
if (code == EQ)
{
emit_insn (gen_negdf2 (temp, temp));
emit_insn (gen_fseldfsf4 (operands[0], temp, operands[0], operands[3]));
}
if (code == NE)
{
emit_insn (gen_negdf2 (temp, temp));
emit_insn (gen_fseldfsf4 (operands[0], temp, operands[3], operands[0]));
}
}
else
{
temp = gen_reg_rtx (SFmode);
emit_insn (gen_subsf3 (temp, op0, op1));
emit_insn (gen_fselsfsf4 (operands[0], temp, operands[2], operands[3]));
if (code == EQ)
{
emit_insn (gen_negsf2 (temp, temp));
emit_insn (gen_fselsfsf4 (operands[0], temp, operands[0], operands[3]));
}
if (code == NE)
{
emit_insn (gen_negsf2 (temp, temp));
emit_insn (gen_fselsfsf4 (operands[0], temp, operands[3], operands[0]));
}
}
DONE;
}")
(define_insn "fselsfsf4"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f") [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(if_then_else:SF (ge (match_operand:SF 1 "gpc_reg_operand" "f") (if_then_else:SF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
(const_int 0)) (const_int 0))
...@@ -2802,6 +2871,15 @@ ...@@ -2802,6 +2871,15 @@
"fsel %0,%1,%2,%3" "fsel %0,%1,%2,%3"
[(set_attr "type" "fp")]) [(set_attr "type" "fp")])
(define_insn "fseldfsf4"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(if_then_else:SF (ge (match_operand:DF 1 "gpc_reg_operand" "f")
(const_int 0))
(match_operand:SF 2 "gpc_reg_operand" "f")
(match_operand:SF 3 "gpc_reg_operand" "f")))]
"TARGET_PPC_GFXOPT"
"fsel %0,%1,%2,%3"
[(set_attr "type" "fp")])
(define_insn "negdf2" (define_insn "negdf2"
[(set (match_operand:DF 0 "gpc_reg_operand" "=f") [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
(neg:DF (match_operand:DF 1 "gpc_reg_operand" "f")))] (neg:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
...@@ -2898,9 +2976,9 @@ ...@@ -2898,9 +2976,9 @@
"fsqrt %0,%1" "fsqrt %0,%1"
[(set_attr "type" "dsqrt")]) [(set_attr "type" "dsqrt")])
;; For SMIN, SMAX, UMIN, and UMAX, we use DEFINE_EXPAND's that involve a fsel ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
;; instruction and some auxiliary computations. Then we just have a single ;; fsel instruction and some auxiliary computations. Then we just have a
;; DEFINE_INSN for fsel and the define_splits to make them if made by ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
;; combine. ;; combine.
(define_expand "maxdf3" (define_expand "maxdf3"
...@@ -2959,7 +3037,76 @@ ...@@ -2959,7 +3037,76 @@
(match_dup 2)))] (match_dup 2)))]
"") "")
(define_insn "" (define_expand "movdfcc"
[(set (match_operand:DF 0 "gpc_reg_operand" "=f")
(if_then_else:DF (match_operand 1 "comparison_operator" "")
(match_operand:DF 2 "gpc_reg_operand" "f")
(match_operand:DF 3 "gpc_reg_operand" "f")))]
"TARGET_PPC_GFXOPT"
"
{
rtx temp, op0, op1;
enum rtx_code code = GET_CODE (operands[1]);
if (! rs6000_compare_fp_p)
FAIL;
switch (code)
{
case GE: case EQ: case NE:
op0 = rs6000_compare_op0;
op1 = rs6000_compare_op1;
break;
case GT:
op0 = rs6000_compare_op1;
op1 = rs6000_compare_op0;
temp = operands[2]; operands[2] = operands[3]; operands[3] = temp;
break;
case LE:
op0 = rs6000_compare_op1;
op1 = rs6000_compare_op0;
break;
case LT:
op0 = rs6000_compare_op0;
op1 = rs6000_compare_op1;
temp = operands[2]; operands[2] = operands[3]; operands[3] = temp;
break;
default:
FAIL;
}
if (GET_MODE (rs6000_compare_op0) == DFmode)
{
temp = gen_reg_rtx (DFmode);
emit_insn (gen_subdf3 (temp, op0, op1));
emit_insn (gen_fseldfdf4 (operands[0], temp, operands[2], operands[3]));
if (code == EQ)
{
emit_insn (gen_negdf2 (temp, temp));
emit_insn (gen_fseldfdf4 (operands[0], temp, operands[0], operands[3]));
}
if (code == NE)
{
emit_insn (gen_negdf2 (temp, temp));
emit_insn (gen_fseldfdf4 (operands[0], temp, operands[3], operands[0]));
}
}
else
{
temp = gen_reg_rtx (SFmode);
emit_insn (gen_subsf3 (temp, op0, op1));
emit_insn (gen_fselsfdf4 (operands[0], temp, operands[2], operands[3]));
if (code == EQ)
{
emit_insn (gen_negsf2 (temp, temp));
emit_insn (gen_fselsfdf4 (operands[0], temp, operands[0], operands[3]));
}
if (code == NE)
{
emit_insn (gen_negsf2 (temp, temp));
emit_insn (gen_fselsfdf4 (operands[0], temp, operands[3], operands[0]));
}
}
DONE;
}")
(define_insn "fseldfdf4"
[(set (match_operand:DF 0 "gpc_reg_operand" "=f") [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
(if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "f") (if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "f")
(const_int 0)) (const_int 0))
...@@ -2968,6 +3115,15 @@ ...@@ -2968,6 +3115,15 @@
"TARGET_PPC_GFXOPT" "TARGET_PPC_GFXOPT"
"fsel %0,%1,%2,%3" "fsel %0,%1,%2,%3"
[(set_attr "type" "fp")]) [(set_attr "type" "fp")])
(define_insn "fselsfdf4"
[(set (match_operand:DF 0 "gpc_reg_operand" "=f")
(if_then_else:DF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
(const_int 0))
(match_operand:DF 2 "gpc_reg_operand" "f")
(match_operand:DF 3 "gpc_reg_operand" "f")))]
"TARGET_PPC_GFXOPT"
"fsel %0,%1,%2,%3"
[(set_attr "type" "fp")])
;; Conversions to and from floating-point. ;; Conversions to and from floating-point.
(define_expand "floatsidf2" (define_expand "floatsidf2"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment