Commit 5656a184 by Eric Christopher

predicates.md (vector_all_ones_operand): New.

2006-06-29  Eric Christopher  <echristo@apple.com>
            Evan Cheng  <evan.cheng@apple.com>

        * predicates.md (vector_all_ones_operand): New.
        (nonimmediate_or_sse_const_operand): Ditto.
        * config/i386/i386-protos.h (standard_sse_constant_opcode): Declare.
        * config/i386/i386.c (standard_sse_constant_opcode): Define.
        (standard_sse_mode_p): Ditto.
        (standard_sse_constant_p): Add case for -1 vector.
        (ix86_expand_vector_move): Try to use.
        * sse.md (*mov<mode>_internal): Use nonimmediate_or_sse_const_operand.
        Call standard_sse_constant_opcode.
        (*movv4sf_internal): Ditto.
        (*movv2df_internal): Ditto.

From-SVN: r115077
parent c8d560fa
2006-06-29 Eric Christopher <echristo@apple.com>
Evan Cheng <evan.cheng@apple.com>
* predicates.md (vector_all_ones_operand): New.
(nonimmediate_or_sse_const_operand): Ditto.
* config/i386/i386-protos.h (standard_sse_constant_opcode): Declare.
* config/i386/i386.c (standard_sse_constant_opcode): Define.
(standard_sse_mode_p): Ditto.
(standard_sse_constant_p): Add case for -1 vector.
(ix86_expand_vector_move): Try to use.
* sse.md (*mov<mode>_internal): Use nonimmediate_or_sse_const_operand.
Call standard_sse_constant_opcode.
(*movv4sf_internal): Ditto.
(*movv2df_internal): Ditto.
2006-06-29 Roger Sayle <roger@eyesopen.com>
* genpreds.c (write_match_code_switch): Correctly use XSTR instead
......
......@@ -43,6 +43,7 @@ extern int standard_80387_constant_p (rtx);
extern const char *standard_80387_constant_opcode (rtx);
extern rtx standard_80387_constant_rtx (int);
extern int standard_sse_constant_p (rtx);
extern const char *standard_sse_constant_opcode (rtx, rtx);
extern int symbolic_reference_mentioned_p (rtx);
extern bool extended_reg_mentioned_p (rtx);
extern bool x86_extended_QIreg_mentioned_p (rtx);
......
......@@ -4622,14 +4622,60 @@ standard_80387_constant_rtx (int idx)
XFmode);
}
/* Return 1 if mode is a valid mode for sse. */
static int
standard_sse_mode_p (enum machine_mode mode)
{
switch (mode)
{
case V16QImode:
case V8HImode:
case V4SImode:
case V2DImode:
case V4SFmode:
case V2DFmode:
return 1;
default:
return 0;
}
}
/* Return 1 if X is FP constant we can load to SSE register w/o using memory.
*/
int
standard_sse_constant_p (rtx x)
{
if (x == const0_rtx)
enum machine_mode mode = GET_MODE (x);
if (x == const0_rtx || x == CONST0_RTX (GET_MODE (x)))
return 1;
return (x == CONST0_RTX (GET_MODE (x)));
if (vector_all_ones_operand (x, mode)
&& standard_sse_mode_p (mode))
return TARGET_SSE2 ? 2 : -1;
return 0;
}
/* Return the opcode of the special instruction to be used to load
the constant X. */
const char *
standard_sse_constant_opcode (rtx insn, rtx x)
{
switch (standard_sse_constant_p (x))
{
case 1:
if (get_attr_mode (insn) == MODE_V4SF)
return "xorps\t%0, %0";
else if (get_attr_mode (insn) == MODE_V2DF)
return "xorpd\t%0, %0";
else
return "pxor\t%0, %0";
case 2:
return "pcmpeqd\t%0, %0";
}
gcc_unreachable ();
}
/* Returns 1 if OP contains a symbol reference */
......@@ -8894,7 +8940,8 @@ ix86_expand_vector_move (enum machine_mode mode, rtx operands[])
to handle some of them more efficiently. */
if ((reload_in_progress | reload_completed) == 0
&& register_operand (op0, mode)
&& CONSTANT_P (op1) && op1 != CONST0_RTX (mode))
&& CONSTANT_P (op1)
&& standard_sse_constant_p (op1) <= 0)
op1 = validize_mem (force_const_mem (mode, op1));
/* Make operand1 a register if it isn't already. */
......
......@@ -678,11 +678,44 @@
return 1;
})
;; Return 1 when OP is operand acceptable for standard SSE move.
/* Return true if operand is a vector constant that is all ones. */
(define_predicate "vector_all_ones_operand"
(match_code "const_vector")
{
int nunits = GET_MODE_NUNITS (mode);
if (GET_CODE (op) == CONST_VECTOR
&& CONST_VECTOR_NUNITS (op) == nunits)
{
int i;
for (i = 0; i < nunits; ++i)
{
rtx x = CONST_VECTOR_ELT (op, i);
if (x != constm1_rtx)
return 0;
}
return 1;
}
return 0;
})
; Return 1 when OP is operand acceptable for standard SSE move.
(define_predicate "vector_move_operand"
(ior (match_operand 0 "nonimmediate_operand")
(match_operand 0 "const0_operand")))
;; Return 1 when OP is nonimmediate or standard SSE constant.
(define_predicate "nonimmediate_or_sse_const_operand"
(match_operand 0 "general_operand")
{
if (nonimmediate_operand (op, mode))
return 1;
if (standard_sse_constant_p (op) > 0)
return 1;
return 0;
})
;; Return true if OP is a register or a zero.
(define_predicate "reg_or_0_operand"
(ior (match_operand 0 "register_operand")
......
......@@ -59,16 +59,13 @@
(define_insn "*mov<mode>_internal"
[(set (match_operand:SSEMODEI 0 "nonimmediate_operand" "=x,x ,m")
(match_operand:SSEMODEI 1 "vector_move_operand" "C ,xm,x"))]
(match_operand:SSEMODEI 1 "nonimmediate_or_sse_const_operand" "C ,xm,x"))]
"TARGET_SSE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
{
switch (which_alternative)
{
case 0:
if (get_attr_mode (insn) == MODE_V4SF)
return "xorps\t%0, %0";
else
return "pxor\t%0, %0";
return standard_sse_constant_opcode (insn, operands[1]);
case 1:
case 2:
if (get_attr_mode (insn) == MODE_V4SF)
......@@ -101,12 +98,20 @@
(define_insn "*movv4sf_internal"
[(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
(match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
(match_operand:V4SF 1 "nonimmediate_or_sse_const_operand" "C,xm,x"))]
"TARGET_SSE"
"@
xorps\t%0, %0
movaps\t{%1, %0|%0, %1}
movaps\t{%1, %0|%0, %1}"
{
switch (which_alternative)
{
case 0:
return standard_sse_constant_opcode (insn, operands[1]);
case 1:
case 2:
return "movaps\t{%1, %0|%0, %1}";
default:
abort();
}
}
[(set_attr "type" "sselog1,ssemov,ssemov")
(set_attr "mode" "V4SF")])
......@@ -135,16 +140,13 @@
(define_insn "*movv2df_internal"
[(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
(match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
(match_operand:V2DF 1 "nonimmediate_or_sse_const_operand" "C,xm,x"))]
"TARGET_SSE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
{
switch (which_alternative)
{
case 0:
if (get_attr_mode (insn) == MODE_V4SF)
return "xorps\t%0, %0";
else
return "xorpd\t%0, %0";
return standard_sse_constant_opcode (insn, operands[1]);
case 1:
case 2:
if (get_attr_mode (insn) == MODE_V4SF)
......
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